为什么派生类的未定义构造函数可以复制基类c++的私有字段的值

问题描述 投票:0回答:2

当我调用类 B 的复制构造函数时,该构造函数的初始化列表中包含值(string lan, const B& kop),我使用 B(kop),它是一个未定义的复制构造函数。据我了解,编译器然后自己创建这样一个构造函数,并且奇迹般地它设法复制基类的“lan”和“licz”字段,当然还有它自己的“tf”字段。但是,在我看来这是不可能的,因为这两个字段在基类中是私有的,并且基类中需要公共设置器,例如对于“licz”我还没有定义一个,编译器本身会创建这样的设置器吗?尽管如此,程序仍能正确执行。请从技术角度解释这是如何发生的以及编译器如何处理它。

abc.h:

#ifndef ABC_H_INCLUDED
#define ABC_H_INCLUDED
#include <iostream>
#include <string>
#include <iomanip>


using namespace std;


class A
{
private:
    string lan;
    int licz;

public:

    A(string lan, int licz) : lan(lan), licz(licz) {}

    virtual void drukuj() const
    {
        cout<<lan<<" ; "<<licz<<endl;
    }

    string getLen() const
    {
        return lan;
    }

    int getLicz() const
    {
        return licz;
    }

    void setString(string lan)
    {
        this->lan=lan;
    }

};






class B : public A
{
private:
    bool tf;

public:
    B(string lan, int licz, bool tf) : A(lan,licz), tf(tf){}
    B(string lan, const B& kop) : B(kop)
    {
        A::setString(lan);
    }

    void drukuj() const override
    {
        cout<<boolalpha<<A::getLen()<<" ; "<<A::getLicz()<<" ; "<<tf<<endl;

    }





};







#endif // ABC_H_INCLUDED

main.cpp:

#include "abc.h"








int main()
{


A a("obiekt klasy A",1);
B b("obiekt klasy B", 2, true);
B c("kopia obiektu b", b);
a.drukuj();//drukuje wszystkie składowe obiektu a
b.drukuj(); c.drukuj();






    return 0;
}
c++ inheritance
2个回答
0
投票

B
的复制构造函数不可能直接构造
A
的成员,它必须调用
A
的某个构造函数。在这种情况下,它调用
A
的复制构造函数,该构造函数是隐式生成的。

我还没有定义[a setter],编译器自己会创建这样的setter吗? [访问私人会员]

您(或者编译器)不需要 setter 来访问私有成员。您所需要的只是知道其在封闭类中的offset,编译器显然知道这一点。


0
投票

但是,在我看来这是不可能的,因为这两个字段在基类中是私有的,并且基类中需要公共设置器...

如果这种复制不起作用,那么继承的用途将相当有限。公共设置器实际上并不是面向对象,但这是其他地方的讨论。

为了便于说明,请考虑以下示例:

#include <iostream>

struct A {
    A() = default;
    A(const A&) {
        std::cout << "hello\n";
    }
};

struct B : A {
    B() = default;
};

int main() {
    B b;
    B c(b);
}

B
有一个编译器生成的复制构造函数。该复制构造函数使用
A
的复制构造函数来复制
A
子对象,因此输出为:

hello

现场演示

© www.soinside.com 2019 - 2024. All rights reserved.