我正在一个类有一个私有成员的系统上工作,这个私有成员是一个基类指针。这个指针可以指向一个继承的类对象。我希望参数化和复制构造函数能够获取基类类型的指针,并在不删除继承类型的情况下深度复制它。下面是我为演示这个问题而编写的一些代码;我想让c2和c3调用B.print而不是A.print,但不知道如何调用。
#include <iostream>
class A
{
protected:
double a;
double b;
public:
A()
{
a = 0.0;
b = 0.0;
}
A(double a, double b)
{
this->a = a;
this->b = b;
}
A(const A& copy)
{
a = copy.a;
b = copy.b;
}
virtual void print()
{
std::cout << "print A" << std::endl;
std::cout << "a: " << a << ", b: " << b << std::endl;
}
};
class B : public A
{
private:
double c;
public:
B()
{
c = 0.0;
}
B(double a, double b, double c) : A(a, b)
{
this->c = c;
}
B(const B& copy) : A(copy)
{
c = copy.c;
}
virtual void print()
{
std::cout << "print B" << std::endl;
std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}
};
class C
{
private:
A* a;
public:
C()
{
a = nullptr;
}
C(A* a)
{
this->a = new A(*a);
}
C(const C& copy)
{
a = nullptr;
if (copy.a != nullptr)
a = new A(*copy.a);
}
~C()
{
delete a;
a = nullptr;
}
void print()
{
if (a != nullptr)
a->print();
}
};
int main()
{
A* a = new A(3.5, 4.5);
A* b = new B(3.5, 4.5, 5.5);
C c1(a), c2(b), c3(c2);
delete a, b;
c1.print();
c2.print();
c3.print();
}
我尝试过包含可用类型的枚举并单独存储该值,但该程序是不可扩展的,因为它需要为每个添加的继承类型更改开关和枚举。
1条答案
按热度按时间avkwfej41#
您的实际问题在于以下几行:
它 * 显式地 * 创建一个动态类型为
A
的对象,忽略动态类型a
和copy.a
。复制某个对象的真实的动态类型的通常模式是
其他,杂项注解:
让编译器默认它。你也可以默认你的大多数复制构造函数。
C
那样),就使用std::unique_ptr
,它就在那里,它是免费的,它的语义更加明确。this->a
作为数据成员,那么要始终如一地使用它;如果你只是为了消除歧义而使用它,那么只要改变参数/局部变量名,这样它就不会在第一时间冲突。有一些成员命名约定,比如
m_a
或a_
,这使得很容易看到哪些变量是数据成员,消除了歧义,并且比随机散布this->
更少的键入/视觉噪音。仅进行上述变更的工作代码:
注意:即使您 * 确实 * 希望
C
进行深度复制,顶层动态分配也是不必要的,所以我只是将其完全删除,而不是将其更改为也使用unique_ptr
或修复不正确的delete
语句。