在努力保持正确性的同时,我经常发现自己正在编写这样的代码
class Bar;
class Foo {
public:
const Bar* bar() const { /* code that gets a Bar somewhere */ }
Bar* bar() {
return const_cast< Bar* >(
static_cast< const Foo* >(this)->bar());
}
};
Run Code Online (Sandbox Code Playgroud)
对于很多方法,比如bar().编写这些非const方法,手动调用常量方法是乏味的; 此外,我觉得我在重复自己 - 这让我心疼.
我该怎么做才能减轻这个任务?(不允许使用宏和代码生成器.)
编辑:除了litb的解决方案,我也喜欢我自己的解决方案.:)
在我正在编写的程序中出现了以下模式.我希望它不是太做作,但它设法Foo在const方法中改变一个对象Foo::Questionable() const,而不使用任何const_cast或类似的东西.基本上,Foo存储参考FooOwner,反之亦然,并在Questionable(),Foo设法修改本身在一个const方法通过调用mutate_foo()关于它的主人.问题遵循代码.
#include "stdafx.h"
#include <iostream>
using namespace std;
class FooOwner;
class Foo {
FooOwner& owner;
int data;
public:
Foo(FooOwner& owner_, int data_)
: owner(owner_),
data(data_)
{
}
void SetData(int data_)
{
data = data_;
}
int Questionable() const; // defined after FooOwner
};
class FooOwner {
Foo* pFoo;
public:
FooOwner()
: pFoo(NULL)
{}
void own(Foo& foo)
{
pFoo = &foo;
}
void mutate_foo()
{
if …Run Code Online (Sandbox Code Playgroud) 我无法理解哪个编译器在这里有问题(如果有的话).与MS Visual Studio C++相比,以下代码与g ++不同.
#include <iostream>
int main() {
int a = 10; //some random value
int* ptr = &a;
//a temp rvalue of type `const int* const' created in g++
//no temp created in MS Visual Studio
const int* const &alias_for_ptr = ptr;
ptr = 0; //null ptr
if (ptr == alias_for_ptr)
//This will execute in MS Visual Studio C++
//But not in g++
std::cout << "ptr == alias_for_ptr" << std::endl;
else
//This will execute in g++
//But …Run Code Online (Sandbox Code Playgroud) 我有另外一个与安全bool成语有关的问题:
typedef void (Testable::*bool_type)() const; // const necessary?
void this_type_does_not_support_comparisons() const {} // const necessary?
operator bool_type() const
{
return ok_ ? &Testable::this_type_does_not_support_comparisons : 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么在bool_type(typedef的),并this_type_does_not_support_comparisons有const?无论如何,没有人应该通过返回指针实际调用成员函数,对吧?这const有必要吗?会operator bool_type(成员函数)违反常量,正确性,否则?
c++ const member-function-pointers const-correctness safe-bool-idiom
如果我创建一个const值的全局数组,例如
const int SOME_LIST[SOME_LIST_SIZE] = {2, 3, 5, 7, 11};
Run Code Online (Sandbox Code Playgroud)
是否有可能以任何方式修改SOME_LIST?
我怎么写这个SOME_LIST指向一个const内存位置,并且是一个const指针本身(即不能指向其他地方)?
我有一个包含一些指针的结构.我希望这些价值不可修改.但是简单地编写const infront并不会使结构成员不可靠
typedef struct{
int *x;
int *y;
}point;
void get(const point *p,int x, int y){
p->x[0]=x;//<- this should not be allowed
p->y[0]=y;//<- this should not be allowed
}
Run Code Online (Sandbox Code Playgroud)
有人能指出我正确的方向.
编辑:
因此,似乎没有简单的方法来使用函数原型来告诉属于该结构的所有内容都应该是不可修改的
我喜欢一致性.我最近问过使用std::begin与例如的问题std::vector<int>::begin,并且一致的决定似乎是使用前者,因为它更通用.但我想我在泥里找到了一根棍子.有时候,你想传达的是,当你循环通过时,你不会改变容器,因此调用std::vector<int>::cbegin.它将使你有时做你的代码很不对称iter = v.cbegin()等次做iter = begin(v).有没有办法解决这种缺乏对称性的问题,你还会推荐std::begin这种知识吗?为什么C++没有std::cbegin?
我有一个const-correctness问题,我似乎无法解决.这是我的程序的结构:
class Node
{
private:
int id;
std::set<Node*> neighbours;
public:
Node();
Node(int id_p);
void set_id(const int& id_p);
int get_id() const;
void add_neighbour(Node* neighbour);
bool is_neighbour(Node* neighbour) const;
friend bool operator <(const Node& lhs, const Node& rhs);
};
class Graph
{
private:
std::set<Node> node_list;
public:
Graph();
void add_node(int id);
const Node* get_node_by_id(int id) const;
bool has_node(int id) const;
void check_add_node(int id);
void add_edge(int id_1, int id_2);
bool has_edge(int id_1, int id_2) const;
void check_add_edge(int id_1, int id_2);
(...)
};
Run Code Online (Sandbox Code Playgroud)
现在问题是,如果我调用该函数Graph::get_node_by_id() …
我有一段遗留代码的包装器。
class A{
L* impl_; // the legacy object has to be in the heap, could be also unique_ptr
A(A const&) = delete;
L* duplicate(){L* ret; legacy_duplicate(impl_, &L); return ret;}
... // proper resource management here
};
Run Code Online (Sandbox Code Playgroud)
在这个遗留代码中,“复制”对象的函数不是线程安全的(当调用相同的第一个参数时),因此它没有const在包装器中标记。我想遵循现代规则:https : //herbsutter.com/2013/01/01/video-you-dont-know-const-and-mutable/
这duplicate看起来是实现复制构造函数的好方法,除了它不是的细节const。因此我不能直接这样做:
class A{
L* impl_; // the legacy object has to be in the heap
A(A const& other) : L{other.duplicate()}{} // error calling a non-const function
L* duplicate(){L* ret; legacy_duplicate(impl_, &ret); return ret;} …Run Code Online (Sandbox Code Playgroud) 将类的const正确性扩展到其尖头成员的正确方法是什么?在示例代码中,get方法的常量版本是否会创建一个std::shared_ptr其引用计数器与内部成员相同m_b,或者是否重新开始计数0?
class A
{
std::shared_ptr< B > m_b;
public:
std::shared_ptr< const B > get_b( ) const
{
return m_b;
}
std::shared_ptr< B > get_b( )
{
return m_b;
}
}
Run Code Online (Sandbox Code Playgroud)