C++抽象类:构造函数是或否?

use*_*426 59 c++ constructor class abstract

具有一个(或多个)虚拟纯函数的类是抽象的,并且它不能用于创建新对象,因此它没有构造函数.

我正在读一本提供以下示例的书:

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;
};
Run Code Online (Sandbox Code Playgroud)

如果类是抽象的,为什么我们有一个构造函数?它稍后使用此类(Boss是公共派生的Employee):

void Boss::Boss (const char* first, const char* last, double s)
     : Employee (first, last)
Run Code Online (Sandbox Code Playgroud)

JBL*_*JBL 73

当你说具有纯虚函数的类是抽象的并且无法实例化时,你是正确的.但是当你说它不能有一个构造函数时你就错了.

实际上,正如您的示例所示,抽象类可以具有私有成员,可以由此类的成员函数使用.这些成员必须初始化.构造函数是一种方法(例如,在派生类中使用初始化列表,如第二个示例所示),在我看来比init()函数更好.

在答案中编辑我的注释:抽象类可以包含成员变量和潜在的非虚拟成员函数,因此前者的每个派生类都实现特定的功能.

然后,初始化这些成员变量的责任可能属于抽象类(至少总是属于私有成员,因为派生类不能初始化它们,但可以使用一些可能使用/依赖的继承成员函数这些成员).因此,它使抽象类实现构造函数完全合理.

  • 是的!如您所见,抽象类仍然可以具有成员和/或非纯虚拟成员函数(例如,确保每个派生提供特定功能).这并不意味着派生类(或者在多态的情况下操纵指向抽象类实例的指针的人)应该知道该功能的实现细节. (2认同)

ode*_*dsh 22

具有纯虚函数的类无法实例化.预计会有子类扩展它并提供缺少的功能.

这些子类在实例化时将构造基类,它们将调用其超类的构造函数,这就是抽象类在c ++中具有构造函数的原因.

所以你不能直接创建一个实例并直接调用构造函数,但未来的子类将会.


Jur*_*aho 7

这个Employee类有数据,这个数据需要以某种方式初始化。构造函数是一个很好的方法来做到这一点。


Gau*_*v K 6

如果抽象基类没有构造函数,firstname , lastname那么在创建派生类的对象时,如何为派生类的成员赋值?

假设有一个Manager Class派生自Employee它添加Salary数据和实现earning()。NowEmployee是一个抽象类,但它Manager是 a 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;
}
Run Code Online (Sandbox Code Playgroud)