繁体   English   中英

通过值将对象传递给SubClass构造函数,导致SuperClass的构造函数无法调用

[英]Passing object by value to a SubClass constructor leading to SuperClass's constructor not call

我试图实现一个超类“ Person”,并从中继承一些子类。 SubClass的构造函数将传递“ Person”类型的对象,然后使用该对象的成员作为传递值调用父承包商。 如果通过引用将对象传递给SubClass构造函数,则一切正常,但是,如果通过值传递对象,则会发生奇怪的事情。 SubClass对象将创建但不通过父构造函数创建(只是传递的对象的副本将在构造函数结束后创建并销毁)。

class Person
{
private:
    string _name;

public:
    Person (string name) : _name(name){cout << "Person registered.\n";}
    ~Person () {cout << "deleted\n";}
    string getName() {return _name;}
};

class Employee : public Person
{
public:
    Employee (Person p) : Person(p.getName()){};
};

int main()
{
    Person a("Jack");
    Employee b(a);
    cout << a.getName() << "\n";
    cout << b.getName() << "\n";
    cin.get();
    return 0;
}

我期望创建3个对象,并销毁一个,但是创建了2个对象,而一个销毁了。

预期产量:

Person registered.
Person registered.
Person registered.
deleted
Jack
Jack

实际输出:

Person registered.
Person registered.
deleted
Jack
Jack

并且如输出所示,创建了第二个对象,但没有通过构造函数。

关于SubClass对象如何创建的任何想法?

当您定义一个类(或一个结构)时,编译器会根据上下文隐式生成一些函数(例如默认构造函数,析构函数,复制/移动构造函数和复制/移动赋值运算符等)。即您自己是否已定义这些功能之一)。

在这里,当您按值将Person对象a传递给Employee对象b ,编译器将调用隐式生成的副本构造函数,基本上是这样的:

Person (const Person& p) : _name(p._name) { /* add logging */ }

隐式生成的副本构造函数的工作是调用该类所有成员的副本构造函数。

如果您自己用日志记录消息定义了复制构造函数,您将看到它是您期望的3种构造和1种破坏,但是其中一种构造是按复制的,因为编译器将无法进行复制-消除,因为其参数为不是prvalue

注意 :编译器有时可以忽略(即选择不首先执行)复制构造函数调用,而是将实例中要复制的对象实例化为优化。 这意味着用户定义的副本构造函数永远不会有任何副作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM