假设class X我想要返回内部成员的访问权限:
class Z
{
// details
};
class X
{
std::vector<Z> vecZ;
public:
Z& Z(size_t index)
{
// massive amounts of code for validating index
Z& ret = vecZ[index];
// even more code for determining that the Z instance
// at index is *exactly* the right sort of Z (a process
// which involves calculating leap years in which
// religious holidays fall on Tuesdays for
// the next thousand years or so)
return ret;
}
const …Run Code Online (Sandbox Code Playgroud) 我想知道是否可以从const成员函数调用非const成员函数.在下面的示例中,First给出了编译器错误.我明白为什么它会出错,我想知道是否有办法解决它.
class Foo
{
const int& First() const
{
return Second();
}
int& Second()
{
return m_bar;
}
int m_bar;
}
Run Code Online (Sandbox Code Playgroud)
我真的不想讨论这样做的智慧,我很好奇它是否可能.
可能重复:
重复,常量和非常量,getter的优雅解决方案?
假设我有一个c ++类,其成员函数为const重载,如下所示:
Type* DoSomething();
const Type* DoSomething() const;
Run Code Online (Sandbox Code Playgroud)
如果这是一个更大,更复杂的成员,那么如何防止必须两次编写相同的代码?不能从const中调用任何非const函数.从非const中调用const版本会导致一个const指针必须被转换为非const(这有点像imo).
我有重载const和non-constc ++结构的功能.然后,我运行程序,我想知道,它没有模棱两可的错误工作正常.
#include <iostream>
struct St
{
int f() const
{
return 1;
}
int f()
{
return 2;
}
} s;
int main()
{
int ret = s.f();
std::cout<<ret<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以,我只是想知道,为什么编译器不会给"const"和"not-const"函数带来模糊错误?
好的,我做了一些研究,显然在这个主题上有很多关于SO的重复问题,仅举几例:
但是我忍不住再提一下,因为
auto -typed返回值,我实际上是复制函数体,唯一的区别是const函数限定符.const版本和非const版本可能返回彼此完全不相容的类型.在这种情况下,斯科特迈耶斯的const_cast习语,以及"非const功能返回非const"技术都不会起作用.举个例子:
struct A {
std::vector<int> examples;
auto get() { return examples.begin(); }
auto get() const { return examples.begin(); }
}; // Do I really have to duplicate?
// My real-world code is much longer
// and there are a lot of such get()'s
Run Code Online (Sandbox Code Playgroud)
在这种特殊情况下,auto get()返回一个iteratorwhile auto get() const返回一个const_iterator,并且两个不能相互转换(我知道erase(it,it) …
比方说,我有一节课vector<T>.我想实现两个getter方法,分别返回T&和const T&.我不想实现它们.相反,我想只实现const版本,然后在非const方法中重用它的代码const_cast.
template<typename T>
class Vector {
public:
T& operator[](size_t i) {
return const_cast<T&>(
static_cast<const Vector<T>*>(this)->operator[](i));
}
const T& operator[](size_t i) const {
return data[i];
}
private:
T* data;
};
Run Code Online (Sandbox Code Playgroud)
这种方法可能存在哪些陷阱?或者,是否有任何方法可以检查const_cast在任何确切的情况下是否合法?
最后,处理这种重复的const /非const代码的常用方法是什么?
关于C++中const和非const方法之间的区别,我有几个问题.
例:
MyObject* MyClass::objectReference()
const MyObject* MyClass::objectReference() const
Run Code Online (Sandbox Code Playgroud)
我的问题是:
为什么在c ++标准(我看cpp参考站点)中允许两个具有相同签名的变体?
例如:
reference front();
const_reference front() const;
Run Code Online (Sandbox Code Playgroud) 在这个例子中,是c样式的强制转换,int&然后是一个hack类的A未定义行为的接口的赋值?
class A
{
public:
A()
: x(0)
{
}
~A()
{
std::cout << x << std::endl;
}
const int& getX()
{
return x;
}
private:
int x;
};
int main()
{
A a;
int& x = (int&)a.getX();
x = 17;
std::cout << x << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
输出:
17
17
Run Code Online (Sandbox Code Playgroud)
如果是这样,我可以参考标准的哪一部分?此外,有没有任何理由为什么这个编译没有警告?(我在cpp.sh上用c ++ 14测试了-Wall,-Wextra和-Wpedantic)
这个问题已经更新.请查看代码.
以下代码是使用VC++ 2012年11月CTP编译的.Scott Meyers的书" Effective C++ "建议我们应该使用这种方法来避免const和非const成员函数的重复.但是,以下代码会导致警告(级别1).因为WDK构建工具将警告视为错误,所以无法成功编译以下代码.
还有其他更好的方法吗?
struct A
{
int n;
A(int n)
: n(n)
{}
int Get() const
{
return n;
}
int Get()
{
return static_cast<const decltype(*this)&>(*this).Get();
}
};
int main()
{
const A a(8);
//
// warning C4717: 'A::Get' : recursive on all control paths,
// function will cause runtime stack overflow
//
a.Get();
}
Run Code Online (Sandbox Code Playgroud) 我试图通过使用排序谓词为类指针向量创建自定义排序:
struct sort_by_airtime
{
inline bool operator() (const Network *n1, const Network *n2)
{
return (n1->airtime() < n2->airtime());
}
};
Run Code Online (Sandbox Code Playgroud)
对于每个网络,我们按airtime()返回的float进行排序.
现在,我尝试使用如下:
std::vector<Network *> Simulator::sort_networks(std::vector<Network *> netlist, bool sort_airtime) {
std::vector<Network *> new_netlist = netlist;
if(sort_airtime) {
sort(new_netlist.begin(), new_netlist.end(), sort_by_airtime());
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我得到了很多这样的错误:
In file included from Simulator.cpp:7:
Simulator.h: In member function ‘bool Simulator::sort_by_airtime::operator()(const Network*, const Network*)’:
Simulator.h:48: error: passing ‘const Network’ as ‘this’ argument of ‘virtual float Network::airtime()’ discards qualifiers
Simulator.h:48: error: passing ‘const Network’ as ‘this’ argument of …Run Code Online (Sandbox Code Playgroud) 我们先看一下例子。
#include <iostream>
int main()
{
const int constant = 1;
const int* const_p = &constant;
int* modifier = const_cast<int*>(const_p);
*modifier = 100;
std::cout << "constant: " << constant << ", *const_p=" << *const_p;
//Output: constant: 1, *const_p=100
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不知道它在内存架构上是如何实现的。看来编译器在堆栈中占用了额外的内存空间,以便我们可以跟踪值为constant的“原始” 1,以及堆栈中值为 的新内存位置100。是吗?那么,const_cast确实会消耗额外的内存,这是初学者可能没有想到的吗?
我收到以下错误:
Conversion loses qualifiers
Run Code Online (Sandbox Code Playgroud)
尝试在没有代码重复的情况下实现索引运算符时(我将显示代码段):
Point* BufferedList::indexTemp(size_t idx)
{
if (idx >= size) return nullptr;
return &arr[idx];
}
const Point* BufferedList::operator [](size_t idx) const
{
return indexTemp(idx);
}
Point* BufferedList::operator [](size_t idx)
{
return indexTemp(idx);
}
Run Code Online (Sandbox Code Playgroud)
但是,以下有效(这不使用辅助函数indexTemp,它是代码重复):
const Point* BufferedList::operator [](size_t idx) const
{
if (idx >= size) return nullptr;
return &arr[idx];
}
Point* BufferedList::operator [](size_t idx)
{
if (idx >= size) return nullptr;
return &arr[idx];
}
Run Code Online (Sandbox Code Playgroud)
我真的需要两个用于索引的函数(一个返回Point*,另一个返回const Point*)?