const结构的指针成员

时间:2017-05-24 15:55:04

标签: c++ pointers const

我有一个看起来像这样的课程:

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];
    }
};

但现在我可以使用复制构造函数来绕过const实例的S,如下所示:

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 SS都应该通过复制构造函数创建,给定S的实例,使const实例无法修改数据,但非 - const实例可以。

2 个答案:

答案 0 :(得分:1)

通过提供两个不同的复制构造函数,可以在复制构造函数中知道正在复制的对象是否为{1: ['1', 'http://www.tennisabstract.com/cgi-bin/wplayer.cgi?p=VictoriaAzarenka', 'Victoria Azarenka', 'BLR', '1989-07-31'], 2: ['1146', 'Brittany Lashway', 'USA', '1994-04-06']} ,一个参数采用const参数而另一个参数不采用const。编译器将选择与传递的参数匹配的版本。在构造函数中设置一个标志,以便在执行非const操作时抛出错误。

避免问题中显示的泄漏内存的最佳方法是使用类似std::shared_ptr的智能指针而不是原始指针。不幸的是shared_ptr适用于单个对象,而不是数组;可行的解决方法as in this StackOverflow question。我现在不打算尝试解决这个问题,下面的代码仍有漏洞。

要完成,您应该遵循Rule of Three并提供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

答案 1 :(得分:0)

删除S的复制构造函数(和赋值运算符)。创建一个新的代理类(SCopy),其中包含指向S对象的指针(传递给SCopy的构造函数)。然后SCopy将实现const int &operator() const而不是非const版本。

这样就可以在S中实现一个析构函数,它可以释放你当前正在泄漏的内存。