在 C++ 中使用默认构造函数

Posted

技术标签:

【中文标题】在 C++ 中使用默认构造函数【英文标题】:Using default constructors in C++ 【发布时间】:2013-11-15 23:06:43 【问题描述】:

大家好,我是编程入门,对成员初始化和默认构造函数有点不确定。我们正在学习类和结构的基础知识,但我们甚至还没有接触到构造方法或继承,所以我有点领先于课程。我在网上冲浪,但我找不到我的问题的确切答案,所以我想我会在这里问:

class ProductionWorker : public Employee

private:
int shiftNum;
double hourlyPay;

public:



//constructor for ProductionWorker
ProductionWorker(int newShiftNum, double newHourlyPay) : Employee(getEmpName(), getEmpNum())

    shiftNum=newShiftNum;
    hourlyPay=newHourlyPay;

在这个 sn-p 中,我遇到的第一个问题是我收到了一个错误,即 Employee 类没有默认构造函数,经过一些研究,我发现如果一个类继承了另一个类,继承的类需要有一个默认的构造函数。我对成员初始化进行了更多阅读,据我了解,如果我只需使用 ProductionWorker 构造函数初始化 Employee 构造函数,我就可以不再需要继承类的默认构造函数。

这对吗?

传入Employee 构造函数的参数是“getter”,因为我不能直接传入Employee 类中保存的变量,因为它们是私有的,这会导致无法预料的问题吗?

【问题讨论】:

Default constructor for an inherited class 的可能重复项 你的粗体陈述是正确的——如果它被实际使用,你只需要一个默认的构造函数。但是,您似乎正在尝试从基类调用 getter(在调用其构造函数之前!)以初始化基类 - 如果是这种情况,您正在使用自身初始化内存,即一开始没有初始化... 调用尚未构建的类的 getter。我认为这是不可能的。 这很有帮助,谢谢,我试图绕过必须公开声明 Employee 类的变量,但我想这就是我必须做的。 @JtWeidenfeller:不,你不必那样做,那太傻了。 【参考方案1】:

在创建类之前,您无法访问其成员。所以Employee( getEmpName(), getEmpNum() ) 没有意义。你应该将这些值传递给构造函数,然后如果你需要它们,调用访问器。

public ProductionWorker( string name, int num, int shiftNum, double pay ) :
    Employee( name, num )

    this->shiftNum = shiftNum;
    this->hourlyPay = pay;

继承是is a 关系。当您创建ProductionWorker 时,您也在创建Employee。由于Employee 只有一个带有名称和数字的构造函数(我假设),所以它们通常被传递给ProductionWorker,因此它可以正确地创建Employee。如下所述,还有其他选择,但这似乎是这种情况下的合乎逻辑的方式。

【讨论】:

这些参数不一定要传递给ProductionWorker 构造函数。它们可以通过其他方式生成,只是不能使用对象本身的成员。虽然对于这种情况,我认为没有明智的选择。 当我尝试这个时,我得到一个错误,因为 Employee 类中的变量是私有的,这就是为什么我认为我可以只使用一个 getter。但是你是对的,使用未初始化的 getter 是没有意义的。如果我将变量从私有移到公共,它会起作用,但我假设数据应该始终是私有的 它可以编译,但它是未定义的行为。也许您想将现有员工传递给ProductionWorkerProductionWorker( Employee e, ... ) : Employee( e.getEmpName(), e.getEmpNum() ) 但可能因为你正在创建一个新的Worker 它可能是一个新的Employee 一起 @BenjaminLindley 是的,这似乎是该场景的解决方案。 这会起作用,但它的风格很糟糕,原因有两个。一,当您可以将成员放入初始化列表时,在正文中分配。二、故意引入命名冲突。【参考方案2】:

基类不需要有默认构造函数。如果它们没有默认构造函数,则派生类的每个构造函数都需要从其成员初始值设定项列表中显式调用基类构造函数之一。但是,您不应该尝试使用任何成员函数,因为尚未构造对象。您基本上想使用派生类的构造函数参数来确定要传递给基类的值。

在您的具体示例中,Employee 基类似乎想要获取姓名和员工编号。除了派生对象需要的信息之外,您可能还希望将它们传递给派生类。

【讨论】:

【参考方案3】:

我认为你理解正确,但你误用了一个概念。 Employee类构造函数的参数可以是它的setter,因为它们可能允许你设置基类的私有属性。

getter 可以让您获得(毫不奇怪)私有字段的值。

顺便说一下,继承类的构造函数总是会调用基类的构造函数。当然,如果基类具有不接受参数的构造函数,则无需在继承类中显式调用它。

假设你有课程:

class ColorCircle : public Circle

string color;

ColorCircle (string c)

this.color = c;



class Circle 

double diameter;

Circle (double d)

this diameter = d;


如果您想创建ColorCircle,您还必须提供有关其直径的信息,但ColorCircle 的构造函数没有任何位置。这就是为什么ColorCircle 的构造函数应该是这样的:

ColorCircle (string c, double d) : Circle (d)

this.color = c;

当您创建 ColorCircle 时,您只需:

new ColorCircle("red", 2.5);

程序负责将直径值2.5 传递给正确的基类构造函数。

【讨论】:

我使用的是 getter 而不是 setter,我的错误很高兴你发现了这一点。这正是我遇到的问题是我无法使用 Employee 类的变量,因为它们是私有的。如果我创建 ProductionWorker 并且 Employee 的参数是它的设置器,我将如何将值传递给 Employee 构造函数? 希望你现在明白了。 ProductionWorker 的构造函数的一些参数必须传递给基类(Employee 的)构造函数,就像在我的示例中将 double d 传递给 Circle 的构造函数一样。 是的,我现在明白了,我不知道继承可以这样工作。再次感谢您

以上是关于在 C++ 中使用默认构造函数的主要内容,如果未能解决你的问题,请参考以下文章

C++的默认构造函数与构造函数

如何禁止在 C++ 中使用默认构造函数?

C++类-使用默认参数的构造函数

C++类-使用默认参数的构造函数

C++构造和析构

为啥 C++ 构造函数在继承中需要默认参数?