在C++中,传递const引用是一种常见的做法 - 例如:
#include <iostream>
using namespace std;
class X
{
public :
X() {m_x = 0; }
X(const int & x) {m_x = x; }
X(const X & other) { *this = other; }
X & operator = (const X & other) { m_x = other.m_x; return *this; }
void print() { cout << m_x << endl; }
private :
int m_x;
};
void main()
{
X x1(5);
X x2(4);
X x3(x2);
x2 = x1;
x1.print();
x2.print();
x3.print();
} …Run Code Online (Sandbox Code Playgroud) // MyClass.h
namespace MyNamespace {
static const double GasConstant = 1.987;
class MyClass
{
// constructors, methods, etc.
};
}
Run Code Online (Sandbox Code Playgroud)
我以前在MyClass声明中声明了GasConstant(并且在源文件中有一个单独的定义,因为C++不支持const非整数类型的初始化).然而,我需要从其他文件访问它,从逻辑上看,它似乎应该驻留在命名空间级别.
我的问题是,static const在这种情况下会产生什么影响?显然const意味着我无法为GasConstant分配新值,但命名空间中的静态成员意味着什么.这类似于文件范围内的静态,其中成员在单元外是不可访问的吗?
我想知道是否可以从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)
我真的不想讨论这样做的智慧,我很好奇它是否可能.
class Foo
{
int Bar;
public:
int& GetBar() const
{
return Bar;
}
}
Run Code Online (Sandbox Code Playgroud)
这GetBar是一种const方法吗?它实际上并没有改变任何东西,但它为"外部世界"提供了一种改变它的方法.
它甚至重要吗?Const之前还是const之后?我猜测我是const在CGFloat它之前还是之后使它的值CGFloat变为常量,但指针呢?这是否适合Objective-C:
// Example.h
extern CGFloat const kPasscodeInputBoxWidth;
// Example.m
CGFloat const kPasscodeInputBoxWidth = 61.0f;
Run Code Online (Sandbox Code Playgroud) 我有一个指针int* p,并在循环中执行一些操作.我不修改内存,只是阅读.如果我添加const到指针(两种情况,const int* p和int* const p),它可以帮助编译器优化代码吗?
我知道其他优点const,比如安全或自我记录,我会问这个特例.重新提出问题:可以const给编译器任何有用的(用于优化)信息吗?
struct STest : public boost::noncopyable {
STest(STest && test) : m_n( std::move(test.m_n) ) {}
explicit STest(int n) : m_n(n) {}
int m_n;
};
STest FuncUsingConst(int n) {
STest const a(n);
return a;
}
STest FuncWithoutConst(int n) {
STest a(n);
return a;
}
void Caller() {
// 1. compiles just fine and uses move ctor
STest s1( FuncWithoutConst(17) );
// 2. does not compile (cannot use move ctor, tries to use copy ctor)
STest s2( FuncUsingConst(17) );
}
Run Code Online (Sandbox Code Playgroud)
上面的例子说明了如何在C++ 11中,如在Microsoft Visual …
所以这个答案让我想到了将结果赋给new指向a的指针的场景const.AFAIK,没有理由你不能合法地 const_cast将constness带走并在这种情况下实际修改对象:
struct X{int x;};
//....
const X* x = new X;
const_cast<X*>(x)->x = 0; // okay
Run Code Online (Sandbox Code Playgroud)
但后来我想 - 如果你真的想new创建一个const对象怎么办.所以我试过了
struct X{};
//....
const X* x = new const X;
Run Code Online (Sandbox Code Playgroud)
它编译!!!
这是GCC扩展还是标准行为?我在实践中从未见过这个.如果它是标准的,我会尽可能地开始使用它.
我知道,从隐式转换char **到const char **无法做到的,为什么,而且转化为char *const *作品.请参阅底部以获取有关该说明的链接.
除了一件特别的事情外,这一切都是有道理的 所以我有以下代码:
#include <stdio.h>
void
print(const char *const*param)
{
printf("%s\n", param[0]);
}
int
main(int argc, char **argv)
{
print(argv);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我将其编译为C++代码,它编译得非常好.但是,如果相同的代码仅编译为C代码,我会收到错误(好吧,警告,但我们假设-Werror,即将警告视为错误).
GCC:
test.c: In function ‘main’:
test.c:12:11: warning: passing argument 1 of ‘print’ from incompatible pointer type [-Wincompatible-pointer-types]
print(argv);
^
test.c:4:1: note: expected ‘const char * const*’ but argument is of type ‘char **’
print(const char *const*param)
^
Run Code Online (Sandbox Code Playgroud)
铛:
test.c:12:11: warning: passing 'char **' …Run Code Online (Sandbox Code Playgroud) 我写了一个测试程序:
#include <iostream>
#include <type_traits>
using namespace std;
template<class T>
void f(T&& t)
{
cout<<is_const<T>()<<endl;
//++t;
}
int main() {
const int i=0;
f(i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它输出"0",显示T不是常量!这很奇怪.然后我修改了f:
template<class T>
void f(T&& t)
{
cout<<is_const<T>()<<endl;
++t;
}
Run Code Online (Sandbox Code Playgroud)
然后是编译器错误,说我们正在修改只读t.那么t可修改与否?在我的计划中有任何错误的假设吗?