常量结构的指针成员
Pointer members of const struct
我有一个看起来像这样的类:
class S
{
public:
int* data;
S() : data(new int[10]) {}
};
构造函数分配10 个整数的内存,默认复制构造函数按预期仅复制指针本身而不是内容。
即使有一个S
实例具有const
修饰符,我也可以修改data
指向的数据,因为该数据本身没有const
修饰符。我可以通过data
私有并且仅允许通过非const
方法进行写入访问来避免这种情况,如下所示:
class S
{
private:
int* data;
public:
S() : data(new int[10]) {}
int& operator(size_t i)
{
return data[i];
}
const int& operator(size_t i) const
{
return data[i];
}
};
但是现在我可以使用复制构造函数来规避S
实例的const
性,如下所示:
void main()
{
const S a; // Allocates memory
S b(a); // Also points to memory allocated for a
b(1) = 3; // Writes to a even though it is not supposed to be mutable
}
解决此问题的优雅方法是什么(可能使用模板)?
const S
实例指向的数据不应仅使用此实例而可变。
复制- 构造函数应仅复制指针,而不应创建数据的深层副本。
const S
和S
都应该可以通过复制构造函数创建,给定一个S
实例,以便const
实例无法修改数据,但非const
实例可以。
通过在复制构造函数中提供两个不同的复制构造函数,可以知道正在复制的对象是否const
,一个采用const
参数,另一个不接受。编译器将选择与传递的参数匹配的版本。在构造函数中设置一个标志,以便在执行非 const 操作时可以引发错误。
避免问题中显示的内存泄漏的最佳方法是使用像std::shared_ptr
这样的智能指针,而不是原始指针。不幸的是,shared_ptr
适用于单个对象,而不是数组;解决方法是可能的,如此堆栈溢出问题。我现在不会尝试解决这个问题,下面的代码仍然有泄漏。
为了完整,您应该遵循三法则,并提供operator=
和析构函数。我把这个留给读者作为练习。
class S
{
private:
int* data;
bool is_const;
public:
S() : data(new int[10]), is_const(false) { data[1] = 42; }
S(const S& other) : data(other.data), is_const(true) {}
S(S& other) : data(other.data), is_const(false) {}
int& operator()(size_t i)
{
if (is_const)
throw std::logic_error("non-const operation attempted");
return data.ptr[i];
}
const int& operator()(size_t i) const
{
return data.ptr[i];
}
};
查看实际操作:http://ideone.com/SFN89M
删除S
的复制构造函数(和赋值运算符)。 创建一个新的代理类 (SCopy
),其中包含指向S
对象的指针(该指针传递给SCopy
的构造函数)。 然后,SCopy
将实现const int &operator() const
而不是非常量版本。
然后,这将允许您在S
中实现析构函数,以释放当前泄漏的内存。
相关文章:
- 从成员指针到整个结构/类的强制转换
- OOP 中的单成员指针
- 使用结构成员指针在C++中填充结构
- 聚合初始化,将成员指针设置为同一结构成员
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 共享 C++ 的数据成员指针
- 如何声明指向成员内容的成员指针m_pmd/m_pmf并访问它们?
- 从类C++外部调用指向成员方法的成员指针
- 结构成员指针是否自动初始化为零?
- 如何删除类内类类型的类成员指针
- 是否打印指向已定义 int 的成员指针
- 指向常量的成员指针
- 通过此指针访问时的成员差异和自身的成员指针(简单的 QT 示例问题)
- 类数据成员指针的非类型模板参数包无法使用 gcc 编译
- 为什么我不能在同一行中定义两个相同类型的类的成员指针
- 将类成员指针传递给 Lambda 捕获列表 c++11
- 在单一实例类中将成员指针设置为 null 的正确方法是什么
- 无法删除在destructor中的成员指针的课程
- 删除对象而不调用成员指针的析构函数
- 当派生类的基类具有成员指针时,对其进行深层复制