哪个更好:
bool MyClass::someQuery() const;
const bool MyClass::someQuery() const;
Run Code Online (Sandbox Code Playgroud)
我一直在使用'const bool',因为我确信我记得听到它是"什么样做的"(例如比较运营商)但我无法在任何地方找到证据,主要是因为它很难谷歌和Intellisense没有帮助任何人;)任何人都可以确认吗?
对我来说,返回const值(这不仅仅是关于bools)更有意义; 它会阻止临时修改,这几乎总是一个程序员的错误.我只是想要一些东西来支持这一点,所以我可以赞美给我的同事们返回const值:)
我知道const指针可以通过几种方式声明:
const int * intPtr1; // Declares a pointer that cannot be changed.
int * const intPtr2; // Declares a pointer whose contents cannot be changed.
// EDIT: THE ABOVE CLAIMS ARE INCORRECT, PLEASE READ THE ANSWERS.
Run Code Online (Sandbox Code Playgroud)
但是在函数参数的上下文中,相同的原理呢?
我认为以下是多余的:
void someFunc1(const int * arg);
void someFunc2(int * arg);
Run Code Online (Sandbox Code Playgroud)
由于someFunc 1和2对指针本身执行pass-by-value,因此someFunc1在给定函数调用中不可能更改原始指针的值.为了显示:
int i = 5;
int * iPtr = &i;
someFunc1(iPtr); // The value of iPtr is copied in and thus cannot be changed by someFunc1.
Run Code Online (Sandbox Code Playgroud)
如果这些都是真的,那么用'const int*ptr'类型arg声明一个函数是没有意义的,对吗?
这段代码出了什么问题,为什么我得错了答案:
class X
{
private:
const int a;
const int& b;
public:
X(): a(10) , b(20)
{
// std::cout << "constructor : a " << a << std::endl;
// std::cout << "constructor : b " << b << std::endl;
}
void display()
{
std::cout << "display():a:" << a << std::endl;
std::cout << "display():b:" << b << std::endl;
}
};
int
main(void)
{
X x;
x.display();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码会给我结果
display():a:10
display():b:1104441332
Run Code Online (Sandbox Code Playgroud)
但是如果我删除默认构造函数中的注释2行,它给出了正确的结果
constructor : a 10
constructor : b 20 …Run Code Online (Sandbox Code Playgroud) 有没有人知道C++编译器提供的任何警告有助于强制执行const正确性?例如,任何包含非const参数的C++方法产生的警告会很好,该参数在方法内部永远不会被修改.我看到有一个名为-Wsuggest-attribute = const的gnu编译器警告; 但是,当我使用此标志时,我收到一条错误消息,表示无法识别.有什么想法吗?
例如,考虑一下:
int sum(int a, int b)
{
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
与
int sum(const int a, const int b)
{
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
第二种方法通常更快吗?
C中的函数参数被复制并发送到函数,因此函数内部的更改不会影响原始值.我的理由是,在sum上面的第二个中,编译器确实知道a并且b没有在函数内部进行修改,所以它只能传递原始值而不先复制它们.这就是为什么我认为第二个sum比第一个更快.但我真的不知道.在sum上面特别简单的例子中,差异(如果有的话)应该是最小的.
编辑:这个sum例子只是为了说明我的观点.我不希望在这个特定的例子中应该有很大的差异.但我想知道在更复杂的情况下const,编译器是否可以利用函数参数中的修饰符来使函数更快.我怀疑编译器总能确定一个参数是否在一个函数内被改变(因此我的第二个问题在下面); 因此我希望当它找到一个const修饰符时,它会做出与没有const修饰符时不同的东西.
问题:一般来说,一个函数在它的参数时会const比它们不是时更快?
问题2:通常,C编译器(理论上)是否总能确定函数内是否更改了函数参数?
我正在尝试const在类中调用函数,但const存在具有相同名称的非函数.
注意:我不能只改变名字.
class MyQuestion
{
void fun()
{
cout<<"a";
}
void fun()const
{
cout<<"b";
}
void call()
{
fun();//<how to call fun() const?
}
};
Run Code Online (Sandbox Code Playgroud) 我有点困惑何时将内存分配给char*以及何时将其指向const字符串.
是的,我明白如果我想修改字符串,我需要分配内存.
但是在我不希望修改我指向的字符串并且只需要传递值的情况下,我应该执行以下操作?与分配内存相比,以下步骤有哪些缺点malloc?
char *str = NULL;
str = "This is a test";
str = "Now I am pointing here";
Run Code Online (Sandbox Code Playgroud) 是否可以在运行时初始化我的类的静态const成员?这个变量在我的程序中是一个常量,但我想将它作为命令行参数发送.
//A.h
class A {
public:
static const int T;
};
//in main method
int main(int argc,char** argv)
{
//how can I do something like
A::T = atoi(argv[1]);
}
Run Code Online (Sandbox Code Playgroud)
如果无法做到这一点,我应该使用的变量类型是什么?我需要在运行时初始化它以及保留常量属性.
我有一个看起来像这样的遗留函数:
int Random() const
{
return var_ ? 4 : 0;
}
Run Code Online (Sandbox Code Playgroud)
我需要在遗留代码中调用一个函数,以便它现在看起来像这样:
int Random() const
{
return var_ ? newCall(4) : 0;
}
Run Code Online (Sandbox Code Playgroud)
问题是我收到了这个错误:
In member function 'virtual int Random() const':
class.cc:145: error: passing 'const int' as 'this' argument of 'int newCall(int)' discards qualifiers
Run Code Online (Sandbox Code Playgroud)
现在我知道为了解决这个错误我可以使我newCall()的const函数.但后来我有几个newCall()函数调用,所以现在我必须使所有这些函数调用const.等等,直到最后我觉得我的程序的一半将是const.
我的问题:有没有办法在Random()中调用一个不是const的函数?或者有没有任何想法如何实现newCall()内部Random()而不使我的程序const的一半.
谢谢
-josh
我在技术访谈中被问到这个问题:
constC++中的a 和宏有什么区别?
我的回答是宏是一个预处理器指令,如果使用宏,可能很难调试应用程序,因为它在编译之前被常量表达式替换,而a const可以有类型标识符并且易于调试.
任何人都可以指出任何其他差异,哪些应该是首选?
编辑:
来自IBM C++文档:
以下是一些区别
#define和const类型修饰符:
该
#define指令可用于为数字,字符或字符串常量创建名称,而可声明任何类型的const对象.const对象受变量的作用域规则约束,而使用的常量不受约束
#define.与const对象不同,宏的值不会出现在编译器使用的中间源代码中,因为它们是内联扩展的.内联扩展使得调试器无法使用宏值.宏可以用在常量表达式中,例如数组绑定,而
const对象则不能.(我认为我们肯定需要使用宏来定义array_size.编译器不会对宏进行类型检查,包括宏参数.
const ×10
c++ ×8
c ×2
function ×2
pointers ×2
const-cast ×1
constructor ×1
macros ×1
malloc ×1
overloading ×1
reference ×1
return-value ×1
static ×1
string ×1