c++中的继承.为什么是错的
Inheritance in c++. Why is it wrong?
class Human
{
protected:
string name;
public:
Human () : name ("Jim") {}
Human (string n) : name (n) {}
};
class Adult : public Human
{
private:
string passportId;
public:
Adult ()// : name ("Eric"), passportId ("N0123") - *THIS IS ERROR*
{
// this is ok
name = "Eric";
passportId = "N0934956";
}
Adult (string n, string id)// : name(n), passportId(id) *THIS IS ERROR*
{
// this is ok
name = n;
passportId = id;
}
};
所以我们有基类Human和派生类Adult。在代码中(这里是构造函数的实现),您可以看到注释行。
为什么在这种情况下使用这样的初始化是错误的?
Adult (string n, string id) : name(n), passportId(id) {} // *THIS IS ERROR*
正确的格式是:
Adult(string n, string id) : Human(n), passportId(id) {}
初始化列表用于初始化基类和您自己的成员。你不需要初始化基的成员,它们会自己初始化。
使用初始化列表,你只能初始化你自己的成员变量。
你必须在初始化列表中使用Human
构造函数:
Adult (string n, string id)
: Human(n), passportId(id)
{}
基类在派生类之前被构造,因此您将无法在初始化列表中实例化基类的成员。
但是,您可以在初始化列表中调用基类的构造函数,如下所示
Adult() : Human("Eric"), passportId("N0123") { }
成员初始化器列表(即构造函数中:
之后的初始化器)只能初始化基类和构造函数类的成员。初始化基类的成员是基类构造函数的工作。
在执行Adult
的成员初始化列表之前,调用并执行基类的默认构造函数。在基类子对象初始化期间,将构造(并初始化)成员name
(它是基类的成员)。这意味着,在执行派生类的成员初始化列表时,name
已经存在,这就是为什么您的程序是病态的。
你应该做的是:选择合适的基类构造函数,以便正确初始化name
。你可以这样做:
Adult (string n, string id) : Human(n), passportid(id) {}
希望对你有帮助。
这不起作用,因为您试图访问尚未构造的对象的成员。你能做的是
class Human
{
protected:
string name;
public:
Human () : name ("Jim") {}
Human (string n) : name (n) {}
};
class Adult : public Human
{
private:
string passportId;
public:
Adult () : Human ("Eric"), passportId ("N0123")
{
}
Adult (string n, string id) : Human(n), passportId(id)
{
}
};
可以工作,因为它指示编译器用给定的值创建对象的基类部分。稍后在代码中——正如您已经在构造函数中所做的那样——您可以访问受保护的成员。
因为您的派生类Adult
包含Human
作为对象,并且您必须调用其构造函数才能创建它。当Adult
对象死亡时,按相反顺序调用析构函数。首先是Adult
的析构函数,然后是Human
的析构函数
第一次初始化时:
Adult ()// : name ("Eric"), passportId (N0123) - *THIS IS ERROR*
您可能忘记了passportId周围的"
,在第二个:
Adult (string n, string id)// : name(name), passportId(id) *THIS IS ERROR*
我认为你混淆了n
和name
,而且,看起来你应该像这样调用父构造函数:
Adult (string n, string id) : Human(n), passportId(id)
你把name和n搞混了吗?
Adult (string n, string id) : name(n), passportId(id) {}
相关文章:
- 为什么在保护模式下继承升级不起作用
- 如果'C'公开继承'B',B 私下继承'A',为什么我不能在"C"中创建"A"的对象?
- 为什么除了继承聚合结构之外,结构为空,无法聚合初始化?
- 为什么我不能在主函数之外定义一个类的对象(它继承了另一个类)?
- 为什么继承的结构成员在联合中无法访问?
- 为什么继承的受保护构造函数不能公开?
- 为什么继承的函数会更改基类中的成员变量,而不是与名为它的对象同名的对象
- 为什么继承的函数忽略了在原始函数中调用的重写函数?
- 为什么继承的受保护操作员=()有公共访问权限
- 为什么C++继承不允许基类的公共成员继承到派生类的私有成员?
- C++为什么继承不起作用
- 为什么继承值打印两次
- 为什么继承顺序或映射会影响 vftable 的下标?(对于 VSC 表示C++)
- 为什么继承不会增加大小,但成员会增加大小
- 为什么继承的函数隐藏在这个代码的基类中
- 为什么继承QSortFilterProxyModel时没有调用filterAcceptsRow ?
- 为什么继承失败(使用超类的方法)
- 在完全专门化中,为什么继承使前向声明(没有定义)不再足够?
- 为什么继承的构造函数不应该继承默认参数?
- 为什么继承影响异常处理