C++:如何创建一个临时对象,包含一个指针 - 常量或非常量,具体取决于上下文
C++: How to create a temporary object, containing a pointer - const or non-const, depending on context?
我想在向量中保存一些Data
结构。这些结构通过索引(而不是指针(引用其他结构,以节省内存并使序列化更容易。为了遵循这些索引,我创建了一个类DataView
,它为它提供了一个舒适的界面。它看起来像这样:
#include <iostream>
#include <vector>
struct Data
{
int id_next;
int id_prev;
int value;
};
class Foo;
class DataView
{
Foo * foo;
int index;
public:
DataView( Foo * foo_, int index_ )
: foo( foo_ ), index( index_ )
{
}
DataView next() const;
DataView prev() const;
int value() const;
int & value();
int id() const
{
return index;
}
};
class Foo
{
std::vector<Data> data;
public:
friend class DataView;
DataView dataview( int index )
{
return DataView( this, index );
}
Foo()
{
data.resize( 5 );
for ( int i = 0; i < (int)data.size(); i++ )
{
data[i].id_next = (i + 1) % data.size();
data[i].id_prev = (i + 4) % data.size();
data[i].value = i * i;
}
}
void write_cycle( int start_index ) // const
{
DataView seek = dataview( start_index );
do
{
std::cout << "index " << seek.id() << " value " << seek.value() << std::endl;
seek = seek.next();
} while ( seek.id() != start_index );
}
};
DataView DataView::next() const
{
return DataView( foo, foo->data[index].id_next );
}
DataView DataView::prev() const
{
return DataView( foo, foo->data[index].id_prev );
}
int DataView::value() const
{
return foo->data[index].value;
}
int & DataView::value()
{
return foo->data[index].value;
}
int main()
{
Foo foo;
foo.write_cycle( 3 );
foo.dataview( 2 ).value() = 11;
foo.write_cycle( 3 );
return 0;
}
如果我必须区分dataview
方法的常量和非常量变体,就会出现问题。事实上,write_cycle
应该是恒定的,因为它不会改变任何东西。但是,如果我取消注释限定符const
我会收到编译器错误。
错误:将"const Foo"作为"this"参数传递会丢弃限定符 [-fallowive]
如何编写包含常量或非常量foo
指针的DataView
,具体取决于它的构造函数是用常量还是非常量指针调用的?
你说:
这些结构通过索引(而不是指针(引用其他结构,以节省内存并使序列化更容易。为了遵循这些索引,我创建了一个类
DataView
,它为它提供了一个舒适的界面。
这向我表明您不需要支持:
foo.dataview( 2 ).value() = 11;
使用 DataView
仅读取数据。如果您同意这一点,您可以更改DataView
以存储Foo const*
。然后,您可以摆脱非const
版本的DataView::value()
。
class DataView
{
Foo const* foo;
int index;
public:
DataView( Foo const* foo_, int index_ )
: foo( foo_ ), index( index_ )
{
}
DataView next() const;
DataView prev() const;
int value() const;
// Don't need this.
// int & value();
int id() const
{
return index;
}
};
如果一个方法const
,则不允许它执行或提供的任何操作来更改实例。这包括方法调用的任何函数或其他方法,以及对该方法返回的任何成员的引用必须const
,以便将来不能使用它们来修改对象。
因此,如果write_cycle
是const
那么dataview
必须const
并且DataView
必须有一个接受const Foo *
的构造函数。这意味着还必须const
DataView::foo
接受const Foo *
的分配。如果DataView
的客户端希望操纵存储的Foo
,这可能是一个问题。
最终结果,如果没有一堆额外的工作,write_cycle
就无法const
。
要向用户添加R Sahu's
关于将Foo
保留在Dataview
内作为const
的答案,因为它将充当read only
类并且不应该修改Foo
; 您可以将此函数添加到类Foo's
以更新其值:
void Foo::updateValue( int index, const int& value ) {
if ( index < 0 || index >= data.size() ) {
return;
}
data[index].value = value;
}
然后在主文件.cpp内部将如下所示:
Foo foo;
std::cout << "writing cycle of 3" << std::endl;
foo.write_cycle( 3 );
std::cout << "updating index 2 with value of 11" << std::endl;
foo.updateValue( 2, 11 );
std::cout << "writing cycle of 3" << std::endl;
foo.write_cycle( 3 );
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 什么时候在C++中返回常量引用是个好主意
- 代理对象的常量正确性
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 通过多个头文件使用常量变量
- 在cuda线程之间共享大量常量数据
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 是默认情况下分配给char数组常量的值
- 私有类型的静态常量成员
- OpenGL大的3D纹理(>2GB)非常慢
- 类似枚举的计算常量
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 使用常量键但非常量值进行映射
- 为什么`is_open()`非常常量
- 从getter方法返回常量和非常量值
- 阻止const类函数在引用成员上调用非常常量类函数
- C++初始化非常大的常量数组,最佳实践
- 提高c++中非常大的常量的可读性