是否仍调用私有基类构造函数?

Are private base class constructors still called?

提问人:KAMLESH SINGH 提问时间:9/3/2023 最后编辑:Carlo WoodKAMLESH SINGH 更新时间:9/12/2023 访问量:64

问:

#include <iostream>

// first base class
class Vehicle
{
public:
    Vehicle() { std::cout << "This is a Vehicle\n"; }
};

// second base class
class FourWheeler
{
public:
    FourWheeler()
    {
        std::cout << "This is a 4 wheeler Vehicle\n";
    }
};

// sub class derived from two base classes
class Car : private Vehicle, private FourWheeler
{
};

// main function
int main()
{
    // Creating object of sub class will
    // invoke the constructor of base classes?
    Car obj;
    return 0;
}

我本来以为没有输出,但它给出了输出(即它运行超类的构造函数)。为什么会这样?请启发我。

C++ 继承 构造函数 private-methods

评论

0赞 HolyBlackCat 9/3/2023
为什么你期望没有输出?
1赞 john 9/3/2023
如果使用私有继承的类无法运行,那么私有继承的意义何在?Private/protected/public 是编译时检查,而不是运行时检查。

答:

1赞 Siddharth Sagar 9/3/2023 #1

Private 用于描述类的访问控制。继承的类将运行其各自的构造函数,而不考虑私有继承或公共继承。

Private 应该用于定义您不希望暴露给类外部的方法和函数的方法和函数。它并不意味着隐藏或锁定功能。

0赞 Mostafa Mohamed Farag Beshier 9/3/2023 #2

继承中使用的 public、private 和 protected 关键字称为访问修饰符。这些更改继承的基类成员的最大控制级别。 构造函数是无法继承的公共方法,它们在创建对象时仅调用一次。 默认情况下,基类的构造函数由子类的构造函数调用。 如果同一子类中存在多个继承,则其构造函数由相同的继承序列调用。 在您的示例中:

class Car : private Vehicle, private FourWheeler
{
    // The access modifier is private for both base classes.So, all the public and protected inherited members are treated here as private members.
    // All the private members of the base classes will not be inherited to the Car class.
    // You cannot access the inherited members outside the class or when inheriting this class.
    // The constructor of Vehicle class will be called first then FourWheeler class.
    // There is no constructor in the Car class so the compiler will generate it by default constructor.
    // It also will generate the copy constructor and other functions like assignment operator and move operator by default.

};

在这里,编译器将此类代码扩展到此。

class Car : private Vehicle, private FourWheeler
{
public:
    Car() = default; // default constructor
    Car(Car& source) = default; // copy constructor

};

构造函数将按如下方式扩展:

class Car : private Vehicle, private FourWheeler
{
public:
    Car(){
        //default things.
    }
};

但是基类的构造函数调用在哪里。 即使你这样编写子类的构造函数,它也会被扩展为调用所有基类的构造函数,并将其默认参数传递给调用。 您的班级代码将扩展为:

class Car : private Vehicle, private FourWheeler
{
public:
    Car(): Vehicle(), FourWheeler(){
        //default things.
    }
};

“:” 后面的部分称为直接初始化。直接初始化的优先级高于大括号中的部分。 因此,如果子类构造函数中有这样的语句:

class Car : private Vehicle, private FourWheeler
{
public:
    Car() : Vehicle(), FourWheeler() {
        cout << "I have created a car!\n";
    }

};

这将是输出:

This is a Vehicle
This is a 4 wheeler Vehicle
I have created a car!