Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 你如何抛弃const';函数引用对象(并访问非常量方法)时的默认值?_C++_Casting_Constants - Fatal编程技术网

C++ 你如何抛弃const';函数引用对象(并访问非常量方法)时的默认值?

C++ 你如何抛弃const';函数引用对象(并访问非常量方法)时的默认值?,c++,casting,constants,C++,Casting,Constants,我有一份我想保护的数据备份,因此我将其设置为const。我需要两次违反constness,一次将原始数据存储到其中: fgBlocks.CopyInto((BlkArray&)backUpCopy); w、 r.t result CopyInto(BlkArray &replica) const {/**/} 同样,当我调用它的RemoveAll()时,这是一个非常量方法: ((BlkArray)backUpCopy).RemoveAll(true); 第一个演员阵容(如上

我有一份我想保护的数据备份,因此我将其设置为
const
。我需要两次违反
const
ness,一次将原始数据存储到其中:

fgBlocks.CopyInto((BlkArray&)backUpCopy);
w、 r.t

result CopyInto(BlkArray &replica) const {/**/}
同样,当我调用它的
RemoveAll()
时,这是一个非常量方法:

((BlkArray)backUpCopy).RemoveAll(true);
第一个演员阵容(如上所示,
(BlkArray&)
)正确吗?这是一个间接的方面,我以前没有投到。然后,我将再次添加另一个未使用的方面,即丢弃调用对象方法的
const
ness,这是编译器不接受的,如上所示

成员声明如下:

BlkArray fgBlocks;
const BlkArray backUpCopy;
我试图扩展Correa的解决方案,因此:

    BlkArray *pBUCopy = (BlkArray *)&backUpCopy;
    fgBlocks.CopyInto(*pBUCopy);
现在唯一的问题是编译器由于以下原因失败

具有“const”类型“const BlockArray”的未初始化成员“MyClass::backUpCopy”


请注意,如果您这样做,并且对象确实是
const
,那么在丢弃
const
属性后对其进行修改是未定义的行为

fgBlocks.CopyInto(const_cast<BlkArray&>(backUpCopy));
fgBlocks.copyito(const_cast(backUpCopy));
另一个也一样:

const_cast<BlkArray&>(backUpCopy).RemoveAll(true);
const_cast(backUpCopy).RemoveAll(true);

您可以通过简单地将所有方法标记为
const
来避免这个问题,除了
RemoveAll
CopyFrom
之外,后者是
BlkArray
的一种方法,它要么实现逻辑,要么将
*此
传递到
CopyInto


为了更安全地确定谁可以清除数据/将新内容复制到其中,您可以将这些方法设置为私有,并将必要的类声明为好友,或者使用来保护这两个方法。

通过查看Qt的内部结构,我学到了一个小技巧:

MyClass:circunventConst() const
{
    MyClass* that = const_cast<MyClass*>(this);
    that->myProtectedVariable = value;
}
MyClass:circunventConst()常量
{
MyClass*that=const_cast(this);
该->myProtectedVariable=值;
}

对象实际上是
const
。除了上述调用之外,我还将其设置为
const
成员,并且仅以只读的方式使用。对
RemoveAll
的调用是在包含类的析构函数中进行的。@John不幸的是,如果不引起UB,您就不能执行我当时发布的操作。您可能要做的是将实变量
设为private
而不是
const
,然后对其
进行
const
引用
public
。这样,它所属的类可以修改它,但外部世界只能通过
const
引用查看它,因此无法更改它。@John:为什么需要调用
RemoveAll
?只需让BlkArray的析构函数来处理删除数据的问题。@John那么你,实现者,正试图保护自己不受实现的影响吗?@John:接口(声明)不应该告诉你实现细节(定义)。最好使用
const_cast
,而不是C风格的强制转换。对读者来说,这比康斯特内斯被抛弃更为明显。这比我希望的多了几行,但对我来说似乎是对的,谢谢,我会试一试。这一点都没有帮助(如果,正如海报所说,
myProtectedVariable
const
,那么无论
*这
const
,都是
const
). 此外,如果
*此
实际上是一个
常量
对象,则会导致未定义的行为。Qt这么做太愚蠢了。好吧,我是从内存中说的,所以不能具体说明为什么这么做,或者它是否仍然在Qt的代码中。但这肯定是我第一次看到。当然,对于这个简单的示例,正确的方法是将myProtectedVariable设置为可变的,这样const方法更改它是有效的。也许他们在使用mutable的编译器中发现了bug,并正在解决它,但我只是在尝试。@SethCarnegie:谢谢你!为了安全起见,我会给它起一个非常愚蠢的模糊的名字。@John不仅是指针,还有引用。你的第二句话几乎是正确的,但并不完全正确:它可以使一个指向声明为
const
not
const
的对象的指针或引用非常好;当您通过非
const
指针或引用修改声明为
const
的对象时,会发生一件坏事,该指针或引用是使用
const\u cast
丢弃
const
得到的。然后是你得到UB的时候。考虑它的方式是,
const\u cast
丢弃了引用类型的
const
,但它实际上并没有使底层对象成为非
const