w***g 发帖数: 5958 | 1 不允许出现最左边的const确实不能解决所有问题。见下面的例子
const static int s1 = 1, s2 = 1;
const extern int e1 = 1, e2 = 1;
等价于
int static const s1 = 1, s2 = 1;
int extern const e1 = 1, e2 = 1;
第二种写法更容易混淆。static/extern作用于后面所有的变量(编译成.o后用nm看输出的
变量可以确定),而const作用于int。作用对象交错了。
int const *const s1 = 0, s2 = 1;
第一个const作用于int,所以跟s1和s2都有关。第二个const作用于*只和s1有关。
这个确实比第一个const写前面更变态。
我扛不住了,大家赶紧转java吧。 |
|
z****e 发帖数: 2024 | 2 我们来验证一下这个转换的存在性。
class xyz
{
public:
const xyz& operator+(const xyz &rhs) const{return *this;}
private:
int n;
};
如果你把
const xyz& operator+(const xyz &rhs) const{return *this;}
变成
xyz& operator+(const xyz &rhs) const{return *this;}
就是错的了。
为什么呢:
invalid initialization of reference of type ‘xyz&’ from expression of
type ‘const xyz’
所以,这个例子来验证thrust说的那个implicit conversion to const。 |
|
f*******n 发帖数: 12623 | 3 一个const是关于pointer指向的那些char。另一个是关于pointer变量本身。
const char *
char const *
这两个是一样的。就是说pointer本身可以变,但是不能通过pointer来改指向的char。
char * const
这是说pointer本身不能变,但是可以通过pointer来改指向的char。
const char * const
char const * const
这两个是一样的。就是说pointer本身不能变,也不能通过pointer来改指向的char。 |
|
c*******9 发帖数: 6411 | 4 I see both declaration, which one is better?
const xyz& operator+(const xyz &rhs) const);
const xyz operator+(const xyz &rhs) const;
I am thinking that you should not use const xyz& operator+(const xyz &rhs) const),
return a reference of new value is not a good idea, right? |
|
S*A 发帖数: 7142 | 5
这不是冗余的规则,其实是你不允许出现左边 const 是冗余的规则。
是你自己为了自己(片面)的理解方便强加出来的规则。所以最后为了
补全还是给最左边 const 加个反规则的例外。
const 是个 modifier, 是可以放左边的。其实 C 编译的时候是
把 const 作用在当前 type 的。当 * 出现以后,当前 type 就是
pointer type。所以 const 作用到 pointer 上。
对,const 作用在 typedef pointer就是很好一个例子。
其实只要你真正理解了 C 的编译器是如何工作的,这些左边右边规则
是不需要记住的,你为了记这个不是规则的规则还要加个违反规则的特
例给最左边const。
你只需要知道 modifier 作用在当前 type 上面就可以了。
其他就是最自然的实现。
style guide 指的是 style。就是等价时候可以这样可以那样的一个取向。
但是 pointer const 这个在 * 左边右边就不是 style 了,是 correctness
的问题了。当然不是 style guide cover 的。所以我... 阅读全帖 |
|
t****t 发帖数: 6806 | 6 不过,抛开BJ是怎么写的不谈,如果有
class A {
T& b;
};
const A a;
那a.b引用的对象的确是可以改变的.也就是说这里b的类型是 [const reference to T
(T& const)], 等价于[reference to T (T&)],而不是[reference to const T (const
T&)],和用T* b来定义是一个道理.
注意你不能直接写T& const,这属于语法错误. "const reference"只能通过typedef或
者template来间接的引入,并会被直接忽略.这很好理解,因为reference一旦bind,就不
能rebind,所以和指针不同,它们永远都是const的.[8.3.2, clause 1] |
|
z****e 发帖数: 2024 | 7 const X& operator+(const X& rhs) const;
看到一个声明如上,
const的mem fun 是不能改mem data吧?
那么这种设计干什么呢?进来的是const,里边的自己人也是const,加法,加谁呀? |
|
t****t 发帖数: 6806 | 8 T* can be implicitly converted to const T*. but don't push it too far: T**
can not be implicitly converted to const T**. T** can be implicitly
converted to (T* const *). the standard specifically forbid this [4.4]:
[ Note: if a program could assign a pointer of type T** to a pointer of type
const T** (that is, if line #1
below were allowed), a program could inadvertently modify a const object (as
it is done on line #2). For
example,
int main() {
const char c = ’c’;
char* pc;
const char** pcc = &... 阅读全帖 |
|
r****o 发帖数: 1950 | 9 关于const和volatile,我们知道他们可以修饰变量,也可以修饰指针,如下所述。
int a;
const int *p = a;
volatile int *p = a;
//结论:这里const或volatile修饰a,
int * const p = a;
int * volatile p = a;
//结论:这里const或volatile修饰指针p
我想问的是如果这里是pointer-to-pointer,例如
const int **p = a;
volatile int **p = a;
或
int ** const p = a;
int ** volatile p = a;
上面的结论是否还成立?另外,如果const或volatile修饰指针,这里是修饰的第几级
指针呢?还是一级指针和二级指针都被修饰? |
|
S*A 发帖数: 7142 | 10
那 const int * ptr; 如何算?
const int *ptr 和 int const *ptr 是一样的。
你不需要这样区分左边和右边。 const 是作用在
当前的 declaration type 上面。
int * ptr 编译器 AST 是这样的:
const int * ptr 编译的 AST是
[const]
int * const ptr 的 AST 是
[const]
|
|
c**y 发帖数: 172 | 11 By using "const", it indicates that the copy constructor would not change
anything of the parameter being passed.
A non-const reference parameter is automatically cast into a const reference
by the compiler.
However, if the copy constructor is defined with a non-const reference
parameter, then passing a const reference can't go through because the
compiler can't cast the const reference automatically to a non-const
reference. In C++, dynamic_cast is needed to get rid of consistness of the
object... 阅读全帖 |
|
G***l 发帖数: 355 | 12 补充下1
具体来说,const声明的变量不是不能修改,而是不能调用任何非const的方法/
operator。insert不是一个const方法。如果你在const方法里改怎么办?做不到,因为
const方法里也只能调用const方法。
不过你可以把某个成员定义为mutable。This is the evil part of c++。
const是c++里重要的基础概念之一,lz有时间多看看书。 |
|
b*****e 发帖数: 474 | 13 foo 是一个返回 const int 的函数。
这 const 是多余的。因为return 的东西是 r-value, 本来就不能改。
如果是 const char * 或者 const char &, 这里的const 是修饰char, 而不是
整个return type, 所以不是多余的。
也可以写成 char const * 或者 char const &. |
|
s*******d 发帖数: 59 | 14 int main() {
const char c = 'c';
char* pc;
const char** pcc = &pc; //1: not allowed
*pcc = &c;
*pc = 'C'; //2: modifies a const object
}
const char **
是说char 是const,还是说char* 是const? |
|
d****n 发帖数: 130 | 15 1. 一般如果函数的参数是引用或指针类型,而且在函数中不会改变,一般都应该声明
成const,对不对?
2. 那么member function什么时候应该声明成const呢?如果函数不修改类的成员,是
不是也尽量应该声明成const,我的理由是,如果第一条成立,那么类就会经常有const
的object,如果member function不声明成const,就没法调用这个member funciton.
关于const有什么使用的guideline吗? |
|
b***y 发帖数: 2799 | 16 ☆─────────────────────────────────────☆
noid (DoIneedit?) 于 (Tue Jun 3 01:24:54 2008) 提到:
the return value can be const or non-const. If the value is used as the
argument of fuction such as f(a+b), the result of a+b becomes a temporary
object. "Thinking in C++" says the temporary object is automatically const.
As a const, only the const member function can be used. However, my test
case works on non-const member function too. Here it is. What is wrong?
#include
using namespace s |
|
t****t 发帖数: 6806 | 17 typical PaulPierce c++ post: it's hard to find a correct statement.
const implies INTERNAL linkage (not local linkage, there is no such thing as
"local linkage") IF it is not declared extern. [3.5, 3]
extern const int c = 1;
is explicitly allowed by standard. it is even in the example. [3.1, 3] so
combining extern and const WILL work.
defining const int i=1 in every compilation unit is fine. however, linker
will NOT merge them, because each "const int i=1" has internal linkage and
they shall NOT... 阅读全帖 |
|
g****y 发帖数: 436 | 18 搞不明白怎么回事。。。
指针不能自动做const 转换吗?
// file_func.cpp
namespace const_test{
void const_para(const int para) {}
void const_para(const int para, const char** pppara ) {}
}
int main(int argc, char** argv){
const int c_argc = argc; //ok. does not harm
const_test::const_para(c_argc);//ok. type match
const_test::const_para(1); //ok. type match
const_test::const_para(argc); //ok. auto type conversion.
const_test::const_para(para, argv); //error. Can not convert from
... 阅读全帖 |
|
t****t 发帖数: 6806 | 19 no, the point here is to allow temporary object to bind. temporary object
only binds to const reference. for example:
class A {
public:
A(A&);
};
A operator+(const A&, const A&);
A a1;
A a2(a1); // OK
A a3(A()); // wrong
A a4(a1+a2); // wrong
class B {
public:
B(const B&);
};
B operator+(const B&, const B&);
B b1;
B b2(b1); // OK
B b3(B()); // OK
B b4(b1+b2); // OK |
|
i**p 发帖数: 902 | 20 #include
using namespace std;
class Base {
public:
void f() const {}
};
class vBase {
public:
virtual void f() const {}
~vBase() {}
};
main() {
Base b;
//! const Base cb; // To enable it, add Base() {} to the class
const vBase vb;
const vBase vcb;
} |
|
S*A 发帖数: 7142 | 21 那是因为你没有明白 C 里面 const 的确切含义。
你自己望文生意出一个你觉得应该如此的用法。
你这个就是说,ptr 本身是个 const 指针,指的内容是 const。
我不会通过 ptr 来修改指的内容也不会修改这个 ptr 指针指向。
这个指针的初始值是 i 的地址。
废话,你用了 const int *ptr 当然就不允许 *ptr = 什么了。
因为编译器不是总可以看出 ptr 的内容是哪里来的。例如
可以是一个函数调用的返回值。你没法知道被赋予的内容
是不是 const。 就算不是,指针用了 int const * 就是说,
我不通过这个指针来修改指向的内容。
你真要常量可以用 enum。 |
|
m*********a 发帖数: 3299 | 22 你说的东西,我是知道
但是是个人就是想要pointer指得是const int
但是c++中这个const int不是const,是可以改变的
不能用这个pointer来改,谁care
但是const int i=10;
这个就是一个const,无法改变这个i=10这个值
如果这个值赋值给 pointer的花
必须是const int *p=&i;
不能通过int *p=&i;*p=100;来改变 |
|
c**********e 发帖数: 2007 | 23 大家都知道为什么用reference。但为什么要 const reference?
试了一下,如果用const reference,那么不是 const 的输入也可以。
但如果不用 const reference, 那么 const 的输入 object 就不可以。
但是这个问题的标准答案是什么?还望大牛指点。 |
|
t****t 发帖数: 6806 | 24 呵呵,刚好google book可以翻翻前言
你说的那一段看见了, 作者的确证实了
const T === T const, unless T is a macro (textual replacement)
which is what I said.
of course, if you textual replace T with char*, then
const char * != char * const, but that's not what I said |
|
t****t 发帖数: 6806 | 25 如果你叙述没问题, 那就是他问得不对
本身一个function没有const 不const的
类成员方法可以用const修饰, 那也不是"doesn't change a variable's value", 而是说
this的类型是const T * const, 就是不能改变类成员
't
I |
|
I*****y 发帖数: 602 | 26 >const double *cptr = π
定义的是一个指向常量的指针。
但是你最后一句想改变这个应该为常量的值,当然要出错了。
进一步看看:下面const修饰指针和const修饰常量的区别。
const double *ptrPI = 3.14;
double const *ptrPIConst = π
double * constprtPIConst = π |
|
c**********e 发帖数: 2007 | 27 copy constructor 为什么用const reference. 我解释关于为什么用reference是 对的
,对于为什么用const,我的解释是 prevent the constructor from modifying the
object being copied. tnnd他说不对
A::A(const A& rhs) {...}
What does the const mean?
Somebody claims "The question is what const means here? I think it means
that one is prohibited to change the constant reference passed in. In
contrast, I do not think it means that one must pass in a reference of a
constant object to call the copy constructor."
Is he right or wrong? Thanks. |
|
m****s 发帖数: 1481 | 28 static const char* const grades[]={"A","B","C","D","Fail"};
比较糊涂,这里两个const分别定义什么东西是constant呢?谢谢 |
|
d****n 发帖数: 1241 | 29 static和const是不同的。
static是一个storage specifier, 表示两层含义,(1)linkage, (2) storage
duration. 例如有类似下面的定义:
/* global scope */
static int g; /* g的visibility是file-scope */
那么表示变量g的linkage是internal的,在你所定义的文件外是不可见的;其次g具有
static duration storage, 意思是说,g只能在程序开始的时候,初始化一次,同时,
g这个对象在程序运行的过程中都是存在的.
你也可以在一个函数里定义一个static的变量,在这种情况下,这个static变量是
function-scope的。
const是type qualifier, 表示只读性。比如
const int g;
那么g所代表的对象是只读的,对g进行任何形式的写操作(比如直接写或者通过指针)
是undefined behavior. |
|
T*******x 发帖数: 8565 | 30 我觉得wdong关于const的规则说的很好:
1. const 修饰左边紧邻的词语
2. 尽量不要用const修饰右边词语的用法。
所以你这个可以写成
int const * const ptr = &i
语义是清楚的。 |
|
w***g 发帖数: 5958 | 31 最左边的const作用于它immediately右边的东西,你给的例子是对的。
但这是条冗余规则,只要不允许出现最左边的const就不需要这个规则。
所有事情一样能做。
如果想要ptr本身不能改,又要const出现在最左边,就得先定义一个intPtr才行。
上次去google面试时还被问到这个问题,关键那个面试官自己都没弄清楚
const怎么用。我给她解释了半天她也不明白,然后反复说google的
style guide里建议把const放在最左边,所以就一定要那么写。
但他们style guide在这件事上明明就是错的。所以我印象中google的
engineer整体水平前几年下降非常快。 |
|
w***g 发帖数: 5958 | 32 仔细想了一下。我的理解确实是片面的。但是规则应该没错。
所有最左边的const都可以移到它后边地一个类型标识符之后
而保持语义不变。typedef const XXX ...里的XXX必然是
一个类型标识符,所以可以写成typedef XXX const ...。
变量定义的话const和类型标识符XXX之间还可能有static/auto/register/thread_
local这些,需要跳过,但是把const挪到XXX之后还是保持语义不变。
我正在想反例,还没想出来。你给想个看看。 |
|
b***i 发帖数: 3043 | 33 C++里面,如果有一个函数
const int foo()
{
return 5;
}
或者是一个对象
const Object bar()
{
...
}
这里const干啥用的?
我同事说只能赋值给常值变量,比如const int i = foo();但是我试了,好像可以随便。
我觉得他和 const Obj& obj = bar_();混了,如果是返回一个引用。这个时候我们不
希望变量随便改写引用的内容。 |
|
c**y 发帖数: 172 | 34 1) If the parameter is defined as a const, but a non-const is passed, then
the non-const will be cast into a const inside the copy constructor, which
is done by compiler.
2) You're right, it should be const_cast. Thanks for correcting. |
|
K*******i 发帖数: 399 | 35 某本数据结构英文教材上说Top方法是accessor, 返回值的时候栈中还有这个值,因此
可以返回const引用。Pop方法可以没有返回值,但带返回值的Pop方法不允许返回引用
,因为Pop后这个值逻辑上在栈中被删除了。
假如Top和Pop方法的原型是
template
const T& Top() const;
void Pop();
问题是Top方法返回引用也有问题:
如果调用者这样写
T t = S.Top();
这个问题不大,因为是赋值给t
但如果调用者这样写
const T& t = S.Top();
S.Pop();
这样一来,再使用t不就有问题了么? |
|
K*******i 发帖数: 399 | 36 你的意思是:
如果程序员设计栈的时候
const T& Pop();
这个是程序员的问题,面试的时候这样很大可能被拒,被认为是基本原则错误?
如果程序员设计栈的时候
const T& Top() const;
这个是大多数教科书包括STL的做法
调用者这样用:
const T& t = S.Top();
S.Pop();
这个是调用者的问题,而不是程序员的问题?面试的时候基本不会有什么麻烦? |
|
y*******o 发帖数: 6632 | 37 const和你怎么定义class没关系
比如java里面可以final int,和int
const也一样
如果你想要const construct,c++没这个功能,你可以把construct变成private,然后写
一个createInstance method 返回const variable
c |
|
r*****t 发帖数: 286 | 38 const int& 和const int *都好理解, const int f()这里为啥要用const?和int f()
有啥不同? |
|
L*********r 发帖数: 92 | 39 I do not think so.
for a const pointer or reference, there are two different meanings. one is
the pointer can not be changed, the other is the value which the pointer
pointed to can not be changed. it depend on the location of the const
declaration.
for a const function as your sample,
the function can not change the data member of the class.
the function can only call const function.
your sample has a lot of grammer problems.
question.
true |
|
n********r 发帖数: 65 | 40 a simple example:
/***** code begin ************************/
void fn(const int** a)
{
std::cout << a[0][0] << std::endl;
}
int main(void)
{
int** a = new int*;
a[0]=new int;
fn(a);
return 0;
}
/***** code end **************************/
compiling error: int** cannot convert to const int**
I used to use const modifier before all the parameters
that will not change it value in the function,
and it works well if I pass a none const value to that
function. looks like all variabl |
|
t****t 发帖数: 6806 | 41 Holy Standard
4.4 Qualification conversions [conv.qual]
Clause 4, Note:
[Note: if a program could assign a pointer of type T** to a pointer
of type const T** (that is, if line //1 below was allowed), a pro-
gram could inadvertently modify a const object (as it is done on
line //2). For example,
int main() {
const char c = 'c';
char* pc;
const char** pcc = &pc; //1: not allowed
|
|
r*****e 发帖数: 792 | 42 在函数传递参数时const myClass &src 和myClass const &src有什么区别?
上网查了查,没看到和class obj相关的const的文章。
谢了 |
|
t****t 发帖数: 6806 | 43 能不能说说有啥不同? 我试了试好象是一样的嘛. 如果T是int*,
那const T和T const都是int * const. |
|
t*****g 发帖数: 1275 | 44 Yea, I was wrong on that. T = char * doesn't make const T = const char *, it
's more like const (char *) where char * has higher priority. |
|
l**a 发帖数: 423 | 45 class CC {...};
CC CC::operator+(const &right) const;
usage:
result = A+B;
B is the first const, parameter inside the parentheses, could not be changed.
A is the second const, So A cannt be changed either. |
|
X****r 发帖数: 3557 | 46 const int * 是一个指向const int的指针,不是一个指向int的const指针,后者是int
* const |
|
E*****7 发帖数: 128 | 47
So run the following code, it compiles on my machine:
const int *fun(void)
{
const int x=1, y = 2 , z=3 ;
const int volume = x * y * z ;
return &volume ;
}
int main()
{
const int* pt = fun() ;
cout << "*pt=" << *pt << endl;
return 0;
}
// output: *pt=6 |
|
E*****7 发帖数: 128 | 48 Thanks, you are correct! I am learning C++. Let me try the followings:
const int *fun(void)
{
const int x=1, y = 2 , z=3 ;
static const int volume = x * y * z ;
return &volume ;
}
int main()
{
const int* pt = fun() ;
cout << "*pt=" << *pt << endl;
}
Is it correct now? |
|
p***o 发帖数: 1252 | 49 The correct one should be:
X operator+(const X& rhs) const;
e.g. a=b+c is a=b.opeartor+(c), so neither b nor c will be changed. |
|
c*******9 发帖数: 6411 | 50 class Person
{
public:
string name() const;
...
};
Person aperson;
theName = aperson.name();
Question, since name is a const function, does that mean it can only be
called by a const object? the above code is ok, so does that mean that
the object aperson will be implicited converted to "const object" before
calling name()...? otherwise how come it is allowed to call name()...
Thanks. |
|