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
notconst
的对象的指针或引用非常好;当您通过非const
指针或引用修改声明为const
的对象时,会发生一件坏事,该指针或引用是使用const\u cast
丢弃const
得到的。然后是你得到UB的时候。考虑它的方式是,const\u cast
丢弃了引用类型的const
,但它实际上并没有使底层对象成为非const
。