当类包括复制构造函数和赋值运算符时继承的行为
Behaviour of Inheritance when class includes copy constructor and assignment operator
我无法理解这种行为。我有一个a级,
class A
{
public:
int ch;
char *s;
A()
{}
A(char *st):ch(0)
{
s = new char[10];
strcpy(s,st);
}
A(const A& rhs):ch(rhs.ch)
{
s = new char[strlen(rhs.s)+1];
strcpy(s,rhs.s);
}
const A& operator=(const A& rhs)
{
char *temp = new char[strlen(rhs.s)+1];
strcpy(temp,rhs.s);
delete[] s;
s=temp;
ch = rhs.ch;
return *this;
}
~A()
{
delete []s;
}
};
在这之前,一切都按预期进行,我能够测试我的复制构造函数和赋值运算符,它们工作正常。
现在我创建了一个子类B,并且我得到了堆损坏错误。我不明白,这是与A类析构函数有关的问题吗?下面是我的B级
class B:public A
{
public:
int a;
B():a(0){}
};
A
的默认构造函数不会初始化成员s
(指针(:
A()
{}
因此,当使用此构造函数构造元素时,当析构函数删除未初始化的元素时,会发生崩溃:
~A()
{
delete []s;
}
类B
使用A
的默认构造函数,因此会触发此问题。通过正确初始化默认构造函数中的所有成员来避免它:
A() : ch(), s(0)
{ }
要解决您的问题,您所需要做的就是替换:
char *s;
带有
std::string s;
只需通过char *
摆脱手动内存管理,这正是C++为您提供std::string
的原因。
可能是什么问题
您的默认构造函数不接受任何参数,不进行动态分配
如果您通过此构造函数创建类对象,那么您的析构函数最终会delete
返回一个未分配给new
的指针,从而导致Undefined Behavior。
在析构函数中,您delete[] s;
,但在默认构造函数中,您没有new[]
ed s。事实上,您甚至还没有初始化s
。
实例化派生类时会调用基类的默认构造函数,因为您没有初始化基类(: A(...)
(。因此,你不知道你要删除什么,甚至不知道你明天早餐要吃什么,因为这是未定义的行为。
为了保持一致,new[]
在默认构造函数中。为了避免头痛,我建议使用类似std::string
的内容,而不是字符指针。
相关文章:
- 重载Singly Linked List中的赋值运算符
- 使用赋值运算符重载从类中返回jobject
- 标准库类型的赋值运算符的引用限定符
- 复制构造函数、赋值运算符C++
- 标准::变体的赋值运算符
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- 基类和派生类的多态赋值运算符
- 为用户定义的类正确调用复制构造函数/赋值运算符
- CRTP 中的复制赋值运算符 - gcc vs clang 和 msvc
- 为什么初始化时没有调用重载赋值运算符?
- C++中移动赋值运算符的继承
- 如何使用继承(抽象基类)实现移动构造函数和移动赋值运算符
- 使用 c++ 中的赋值运算符进行继承
- 赋值运算符继承
- 未调用/继承子类中的移动赋值运算符
- 为C++中具有多个继承派生类的vtables的基之一调用赋值运算符
- 派生类继承基类赋值运算符
- 除了赋值运算符之外,C++中的哪些运算符不会被继承?
- 派生类是否间接继承基的赋值运算符?
- 当类包括复制构造函数和赋值运算符时继承的行为