我有一个包含数据的抽象基类,我需要为这些数据分配内存,另一个问题是,衍生类有=运算符重载和复制构造函数,我想知道如何确保从类抽象基类复制成员数据的衍生类也将被复制,遵循代码示例:
class A {
public:
A(const char* v) {
value = new char[strlen(v)+1];
strncpy(value, v, strlen(v));
}
A(const A &a) {
value = new char[strlen(a.value)+1];
strncpy(value, a.value, strlen(a.value));
}
virtual ~A() {
delete[] value;
}
A& operator=(const A& a) {
value = new char[strlen(a.value)+1];
strncpy(value, a.value, strlen(a.value));
return *this;
}
const char* get() const {
return value;
}
virtual void do_some() = 0;
private:
char *value;
};
class B: public A {
public:
B(const char *v, const char *n) : A(v) {
name = new char[strlen(n)+1];
strncpy(name, n, strlen(n));
}
B(const B &b) : A(b) {
name = new char[strlen(b.name)+1];
strncpy(name, b.name, strlen(b.name));
}
~B() {
delete[] name;
}
B& operator=(const B& b) {
A::operator=(b);
name = new char[strlen(b.name)+1];
strncpy(name, b.name, strlen(b.name));
return *this;
}
const char *get() const {
return name;
}
void do_some() {
std::cout << name << std::endl;
}
private:
char *name;
};
我的疑问是,在一些C ++的书中说,重载operator =并在抽象基类中声明一个复制构造函数不是一个好主意,那么如何在deriate类中声明一个复制构造函数和operator =并确保基类被正确复制了吗?
在我的项目中,如果我不在抽象基类中使用数据成员,我必须在所有派生类中声明一些数据成员,当然这不止一个,所以我设计了带有数据成员的抽象类,但我不知道是否有更好的方法。
答案 0 :(得分:1)
你正在做的事情有点尴尬,但技术上很好(除了通过在new[]
之前删除赋值运算符中的名称和值而泄漏内存),但是只有你没有计划多重继承。这有点乱,可能就是为什么你所指的任何书都警告它,但你不应该在具有数据成员的类上使用多重继承(一般而言,尤其如此)。
您可能想尝试不同的方法。考虑在基类中使用受保护的辅助函数(或几个)来设置其变量:
class A
{
public:
// ...
private:
char *value;
protected:
void set_value(const char *str)
{
delete[] value; // remember, deleting null does nothing
value = new char[strlen(str)+1];
strncpy(value, str, strlen(str)); // Also, why do you need strncpy?
// You'll get no null-terminator, which leads to major problems
// Consider just strcpy(value, str);
}
};
这样,您可以从任何派生类设置该值,该功能仍然是公共使用隐藏的,您不必为抽象类编写赋值运算符或复制构造函数。当你想到它时,真的没有多大意义,是吗?
它还可以避免这种情况:
A *a = new B;
B *b = new B;
(*a) = (*b); // ...with an assignment operator on A, this should compile.