Denstructor删除已被替换的成员
Denstructor deletes a member which is already replaced?
我对C++世界还很陌生。。。我有一个关于C++中析构函数的问题。
如果有这样的类:
class TestClass {
public:
double *array;
}
当我把一个数组的指针放在*array
上,再放另一个并删除Testclass实例时,我就不能再访问旧的了?
它变成了一个错误:
int main() {
TestClass tc;
tc.array = new double[10];
double *array2 = tc.array;
tc.array[3]=9;
tc.array = new double[10];
delete &tc; // <------------------- this one.
std::cout<<array2[3]<<std::endl;
// std::cout<<tc.array[3]<<array2[3]<<std::endl;
}
如果不存在CCD_ 2并且激活评论线(最后一行(,显示"09",(tc.array[3]!=array2[3]=>tc.array!=array2(这并不意味着tc.arrray不是*array2中的那个??
怎么了?
tc
是一个函数范围的变量(在堆栈上分配(。它没有与new
一起分配。你不能删除它。当函数返回时,它会自动释放
处理原始指针有些棘手,您的类可能会从使用std::vector<double>
而不是原始指针中受益。另一个选择可能是std::unique_ptr<double[]>
,它为您处理删除指针的操作。
也就是说,如果你想尝试一下,你应该知道什么时候删除什么。
tc
是一个自动变量。您没有使用new
创建tc
,因此不应该使用delete
。当它超出范围时(当程序离开创建tc
的块时(,它将被销毁。
您还没有为TestClass
定义析构函数,因此即使在tc
被销毁后,array
指向的内存仍将被分配。析构函数通常看起来是这样的:
~TestClass() {
delete[] array;
}
您还可以直接分配给tc
的内部指针,这很危险。你应该有和new[]
一样多的delete[]
,但在你的程序中不是这样,所以它会泄漏。您通常应该隐藏内部指针,这样在拥有它的对象没有控制权的情况下就无法重新分配它。
为了使手动内存管理正常工作,您应该考虑一些成员功能:
- 复制构造函数
- 移动构造函数
- 复制分配运算符
- 移动分配运算符
- 破坏者
你可以在这里阅读更多关于这些的信息:三/五/零规则
这里有一个例子,说明了上面提到的5个成员函数加上一个默认构造函数、一个以指针为参数的转换构造函数和两个下标运算符的类的外观。
#include <iostream>
#include <utility> // std::move, std::swap, std::exchange
class TestClass {
public:
// default constructor
TestClass() :
array(nullptr) // member initializer
{
std::cout << "default ctorn";
}
// converting constructor - refuse lvalue pointers since we want to make sure
// that we "own" the pointer
TestClass(double*&& p) : array(p) {
std::cout << "converting ctor " << p << "n";
}
// copy constructing without knowledge about the size of the array isn't possible
TestClass(const TestClass&) = delete;
// move construction works though
TestClass(TestClass&& rhs) :
array(std::exchange(rhs.array, nullptr)) // steal pointer from rhs
{
std::cout << "move ctorn";
}
// copy assignment without knowledge about the size of the array isn't possible
TestClass& operator=(const TestClass&) = delete;
// move assignment works though
TestClass& operator=(TestClass&& rhs) {
std::cout << "move assignmentn";
// swap pointers with rhs - let rhs delete[] our current pointer
std::swap(array, rhs.array);
return *this;
}
~TestClass() { // destructor
delete[] array;
}
// subscripting support
double& operator[](size_t idx) { return array[idx]; }
double operator[](size_t idx) const { return array[idx]; }
private: // hide your raw pointer from direct access
double* array;
};
void printer(const TestClass& tc, size_t idx) {
// use const version of operator[] in the class
std::cout << tc[idx] << "n";
}
int main() {
TestClass tc; // default ctor
// use the converting constructor that creates a TestClass object from a pointer.
// It is then move assigned to tc
tc = new double[10];
tc[3] = 1; // use the non-const version of operator[] in the class
printer(tc, 3);
double* a = new double[10];
// tc = a; // this won't work since we don't accept lvalues in assignment
tc = std::move(a); // make an xvalue to allow the assignment. "a" should not be
// delete[]-ed after this since we granted tc the possibillity
// to take ownership the pointer.
tc[3] = 2;
printer(tc, 3);
}
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 对RValue对象调用的LValue ref限定成员函数
- 模板参数替换失败,并且未完成隐式转换
- 为什么使用 "this" 指针调用派生成员函数?
- Denstructor删除已被替换的成员
- 为什么在 ctor 的参数列表中将成员"x"的类型替换为"decltype(x)"会破坏类模板参数推导?
- std::元组作为成员替换,方便宏
- 替换 rapidjson 中成员的值
- 将类转换为过程 API C++:替换成员变量的常用方法?
- 将静态常量成员替换为静态成员函数的优点
- 仅替换成员函数的模板语法
- 当我替换对象时,我需要删除我在类成员中设置的对象吗
- 用变量替换结构成员名称
- C++:将类数组的元素替换为 const 成员
- 无法创建mock类/对象来替换我的类中的私有成员对象的功能,以便在gtest中进行单元测试
- 是否可以用模板函数替换两个相似的成员函数?
- 在树中找到一个节点,并用带有更新私有成员的新节点替换
- 用包含const成员的结构体实例替换堆栈与静态变量
- 指向成员函数的c++指针,替换__closure
- 无法用const成员替换类的e_back实例