Подтвердить что ты не робот

С++ Аннотация Класс: конструктор да или нет?

Класс с одной (или более) виртуальными чистыми функциями является абстрактным и не может использоваться для создания нового объекта, поэтому он не имеет конструктора.

Теперь я читаю книгу, которая делает следующий пример:

class Employee {
   public:
       Employee(const char*, const char*);
       ~Employee();
       const char* getFirstName() const;
       const char* getLastName() const;


       virtual double earnings() const=0  // pure virtual => abstract class
       virtual void print() const

  private:
       char* firstName, lastName;
};

Если класс абстрактный, у нас есть конструктор? Он использует этот класс позже (Boss является общедоступным из Employee):

void Boss::Boss (const char* first, const char* last, double s)
     : Employee (first, last)

Я немного смущен... спасибо заранее

4b9b3361

Ответ 1

Вы правы, когда говорите, что класс с чистой виртуальной функцией является абстрактным и не может быть создан. Но вы ошибаетесь, когда говорите, что у него не может быть конструктора.

Действительно, как показывает ваш пример, абстрактный класс может иметь частных членов, которые могут использоваться функциями-членами этого класса. И эти члены должны быть инициализированы. Конструктор - это способ сделать это (например, с помощью списка инициализации в производном классе, как показывает ваш второй пример), лучше, на мой взгляд, чем функция init(), например.

Редактирование моего комментария в ответе: абстрактный класс может иметь переменные-члены и потенциально не виртуальные функции-члены, поэтому каждый производный класс из первого реализует определенные функции.

Тогда ответственность за инициализацию этих переменных-членов может принадлежать абстрактному классу (по крайней мере, всегда для частных членов, поскольку производный класс не сможет их инициализировать, но может использовать некоторые унаследованные функции-члены, которые могут использовать/полагаться на этих членов). Таким образом, для абстрактных классов идеально подходит для реализации конструкторов.

Ответ 2

Класс с чистой виртуальной функцией не может быть создан. Ожидается, что у него будут подклассы, которые расширят его и предоставят недостающую функциональность.

Эти подклассы будут строить базовый класс при их создании, они вызовут конструктор своего суперкласса, поэтому абстрактные классы имеют конструкторы в С++.

Таким образом, вы не можете создать экземпляр напрямую и вызвать конструктор напрямую, но будущие подклассы будут.

Ответ 3

В классе Employee есть данные, и эти данные необходимо каким-то образом инициализировать. Конструктор - хороший способ сделать это.

Ответ 4

Если базовый абстрактный класс не имеет конструктора, как бы вы назначали значения членам firstname , lastname для любого производного класса, когда вы создаете объект производного класса?

Предположим, что существует Manager Class, полученный из Employee, который добавляет данные Salary и реализует earning(). Теперь Employee является абстрактным классом, но Manager является concrete class и, следовательно, вы можете иметь объект Manager. Но когда вы создаете экземпляр Manager, вам нужно инициализировать/назначать значения членам, унаследованным от base class i.e. Employee. Один из способов состоит в том, что для этой цели у вас может быть setFirstName() & setLastName() в базовом классе, и вы можете использовать их в конструкторе для derived class i.e. Manager или более удобным способом было бы иметь конструктор в base abstract class Employee.

Смотрите код ниже:

#include <iostream>
#include <cstring>
#include <cstdlib>

using namespace std;


class Employee {
   public:
       Employee(const char*, const char*);
       ~Employee();
       const char* getFirstName() const;
       const char* getLastName() const;


       virtual double earnings() const=0;  // pure virtual => abstract class
       virtual void print() const;

  private:
       char* firstname;
       char* lastname;
};

Employee::Employee(const char* first, const char* last){
firstname= (char*) malloc((strlen(first)+1)*sizeof(char));
lastname= (char*) malloc((strlen(last)+1)*sizeof(char));
strcpy(firstname,first);
strcpy(lastname,last);
}

Employee::~Employee(){
free(firstname);
free(lastname);
cout << "Employee destructed" << endl;
}

const char* Employee::getFirstName() const{ return firstname;}
const char* Employee::getLastName() const{ return lastname; }
void Employee::print() const{
      cout << "Name: " << getFirstName() << " " << getLastName() << endl;
      }



class Manager:public Employee{
   public:
      Manager(char* firstname,char* lastname,double salary):
    Employee(firstname,lastname),salary(salary){}

      ~Manager(){}

      double earnings() const {return salary;}

   private:
      double salary;          
};

int main(){

Manager Object("Andrew","Thomas",23000);    
Object.print();
cout << " has Salary : " << Object.earnings() << endl;

    return 0;
}

Ответ 5

firstName и lastName являются частными членами, недоступными для Boss. Весь интерфейс к ним должен присутствовать в классе Employee, включая инициализацию.

Ответ 6

Инициализировать firstName и lastName. В противном случае вам придется написать код, чтобы инициализировать их в конструкторах каждого производного класса

Ответ 7

"Абстрактный класс содержит по крайней мере одну чистую виртуальную функцию. Вы объявляете чистую виртуальную функцию, используя чистый спецификатор (= 0) в объявлении виртуальной функции-члена в объявлении класса."

о

void Boss::Boss (const char* first, const char* last, double s)
     : Employee (first, last)

first и last определены в базовом классе, поэтому для их инициализации нам нужно сделать вызов конструктору базового класса : Employee (first, last)

Ответ 8

Цель абстрактного класса состоит в том, что вы хотите расширить некоторые функции производными классами. Может ли он иметь конструктор? Да, это возможно, и целью является инициализация локальных переменных из базового класса. Вам следует избегать использования публичного конструктора в Abstract и использовать только защищенные.

Пример, который у вас есть, не является хорошим примером. Не знаю, что это за книга, но что плохой пример. Его как определение переменной int с именем переменной "iAmString":).

int iAmString = 12;

Приветствия