继承和复制构造函数 - 如何从基 class 初始化私有字段?

Inheritence and copy constructor - how to init private fields from base class?

我有 2 个 class,AB。在 A 中,我有 3 个私有字段。在 class B 中,我想编写一个复制构造函数,并从 class A 初始化私有字段。但是,这不起作用:

#include <iostream>
#include <string>
using namespace std;

class A
{
    private:

        string *field1;
        string *field2;
        string *field3;
        double num1;

    public:

        A(string *o, string *n, string *m, double a=0)
        {
            field1 = new string(*o);
            field2 = new string(*n);
            field3 = new string(*m);
            num1 = a;
        }

        A(const A& other) {
            field1 = new string(*other.field1);
            field2 = new string(*other.field2);
            field3 = new string(*other.field3);
            num1 = other.num1;
        }

        void show()
        {
            cout << *field1 << " " << *field2 << " " << *field3 << "\n";
        }

        ~A()
        {
            delete field1;
            delete field2;
            delete field3;
        }
};

/*--------------------------------------------------------------------------------------------*/

class B : public A
{
    private :

        double num2;
        double num3;

    public:

        B(double num2, double num3, string *o, string *n, string *num, double a=0) : A(o,n,num,a)
        {
            this->num2 = num2;
            this->num3 = num3;
        }

        B(const B& other) : A(other.field1, other.field2, other.field3, other.num1)
        {
            num2 = other.num2;
            num3 = other.num3;
        }

        void show()
        {
            cout << num2 << " " << num3 << "\n";
            A::show();
        }
};

int main()
{
    string o = "TEXT 111";
    string *optr = &o;

    string n = "TEXT 222";
    string *nptr = &n;

    string *numptr = new string("9845947598375923843");

    A ba1(optr, nptr, numptr, 1000);
    ba1.show();

    A ba2(ba1);
    ba2.show();

    A ba3 = ba2;
    ba3.show();

    B vip1(20, 1000, optr, nptr, numptr, 3000);
    vip1.show();

    B vip2(vip1);
    vip2.show();

    delete numptr;
    return 0;
}

我确实明白,当我从 private 更改为 protected 时,它应该可以工作(当然可以工作)- 但是如何处理我的代码中的情况?问题是:如何在复制构造函数中初始化来自 base class 的私有字段?当前代码出现以下错误:

/home/yak/test.cpp|9|error: ‘std::string* A::field1’ is private|
/home/yak/test.cpp|61|error: within this context|
/home/yak/test.cpp|10|error: ‘std::string* A::field2’ is private|
/home/yak/test.cpp|61|error: within this context|
/home/yak/test.cpp|11|error: ‘std::string* A::field3’ is private|
/home/yak/test.cpp|61|error: within this context|
/home/yak/test.cpp|12|error: ‘double A::num1’ is private|
/home/yak/test.cpp|61|error: within this context|
||=== Build failed: 8 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

您需要从复制构造函数调用父复制构造函数,并为其提供相同的参数。

当你像

那样复制构造B时,你需要做的就是调用A的复制构造函数
B(const B& other) : A(other)
{
    num2 = other.num2;
    num3 = other.num3;
}

因为 B 继承自 A 这是合法的并且 A 将复制 otherA 部分。

另请注意,所有这些指针都是不必要的,并且会使代码更加复杂。我们可以像这样重写它:

class A
{
private:
    string field1;
    string field2;
    string field3;
    double num1;

public:
    A(const string& o, const string& n, const string& m, double a = 0) : field1(o), field2(n), feild3(m), num1(a) {}

    A(const A& other) field1(other.field1), field2(other.field2), feild3(other.feild3), num1(other.num1) {}

    void show()
    {
        cout << field1 << " " << field2 << " " << field3 << "\n";
    }
};

/*--------------------------------------------------------------------------------------------*/

class B : public A
{
private:

    double num2;
    double num3;

public:

    B(double num2, double num3, const string& o, const string& n, const string& m, double a = 0) : A(o, n, num, a), num2(num2), num3(num3) {}

    B(const B& other) : A(other), num2(other.num2), num3(other.num3) {}

    void show()
    {
        cout << num2 << " " << num3 << "\n";
        A::show();
    }
};

使用class B的拷贝构造函数时,应该调用class A的拷贝构造函数。

所以,用这个替换你的代码:

    B(const B& other) : A(other)
    {
        num2 = other.num2;
        num3 = other.num3;
    }

此外,将 class A 中的析构函数声明为虚拟的。我想你也想为 show() 方法这样做。