读书人

五个小疑点100分。兄弟们帮忙看看

发布时间: 2012-02-10 21:27:41 作者: rapoo

五个小问题100分。兄弟们帮忙看看~
1 静态成员初始化的问题:
class Test
{
private:
static const int x = 1;
};

之后类外还需要写 const int Test::x; //感觉这个可写可不写啊。


2 对于有序型的static const 可以直接在类的内部进行初始化。

这里的有序型怎么理解?

3 union内部不能有静态数据成员或引用成员?

我定义了好像编译没有错误。何解?

4
class Text
{
public: void bad(const string &parm)const;
private:char *_text;
}

void Text::bad(const string &parm)const
{
_text = parm.c_str(); //Error

for(int ix = 0; ix < parm.size(); ix++)
_text[ix] = parm[ix]; //OK
}

同样是做修改类成员的操作,为何一个Error一个OK?

5 auto_ptr <int> pi(new int(1024));
if(*pi != 1024)
{
cout < < "*pi != 1024 " < <endl;
}
else
{
*pi *= 2;
cout < < *pi < < endl;
}

这个智能指针用的没问题吧?:)


--------------------------

呵呵,兄弟们解释下吧。一题20分吧。^-^

[解决办法]
1.C++ primer上说一定要写

4.相当于下面
void Text::bad(const string &parm)const//这个const修饰的是this指针
{
(this-> _text )= parm.c_str(); //Error,这是因为this指针是const的

for(int ix = 0; ix < parm.size(); ix++)
(this-> _text)[ix] = parm[ix]; //OK,虽然this是const的,但我们并没有修改
//this指向的内容(即类成员),而是修改_text
//所指向的地址的值,这个值并不是类成员

函数后面的const可以当作修饰了this指针,这样就好理解了。
5.应该没问题。
[解决办法]
1. 静态const变量如果是整型, 字符, 枚举等简单类型(也就是说有序的)在cpp中可以不写.
[解决办法]
4. 函数后加const是说该函数不修改该类的成员变量, Text类中_text是个字符指针变量
_text = parm.c_str(); 当然会错, 因为这是在修改_text, 而
_text[ix] = parm[ix];修改的不是_text, 而是_text指向的数组的某个元素,所以OK
[解决办法]
1) const内部类型 成员不必再类外声明初始化(当然也可以在类外初始化), 没有 const 的 static 则必需要类外初始化

only static const integral data members can be initialized within a class

如果是结果仍热需要在类外初始化

比如
struct s {
int data;
s() : data(0) {}
};

class Test
{
public:
static const s x;
};

const s Test::x;


2)

在c++中,有序型包括字符型、整型、枚举


3)

static 成员变量属于类而不属于实例, 所以

并不会达到联合数据共享的作用

看例子


union U {

static int v;
int a;
};

int U::v = 10;


void main()
{
U a;

a.a = 100;

cout < <sizeof(a) < <endl;
cout < <a.v < <endl;
cout < <a.a < <endl;

}


4)


void Text::bad(const string &parm)const
{
_text = parm.c_str(); // const 函数不能修改类的成员变量,所有出错

for(int ix = 0; ix < parm.size(); ix++)
_text[ix] = parm[ix]; //OK
// _text 是类的成员变量,const函数是不能修改这个 _text 的值得
// 但可以修改 _text 指针指向的内用

}


比如

struct A{
int* data;
A() {
data = new int;
}
~A() {
delete data;
}
};

void main()
{
A s1;
const A* p = &s1;
*(p-> data) = 100;

}


5)

语法每问题



[解决办法]
1)only static const integral data members can be initialized within a class
其它都需要另外
2)
static const int nameSize=16; //有序
static const char name[nameSize]; //非有序
C++中整数类类型(int long char short enum unsigned)都是 有序 的
3)
对于union来说,里面所有的对象要保证存在的时候地址相同(这个是union的规则,不要问我为什么),而static成员不会放在非static成员存在的地方,而且static成员要求整个程序运行期间它都存在,这个又和union犯冲,所以当然不该让它存在。

const成员也有这个意思,你想一般const成员都被编译器展开了,哪里还有这个东西存放的地址啊?再说了就算没被展开,他如果被分配在某个地方,这块地方肯定不能更改,这样的话,岂不是union就不能修改了?那还要它有什么用?所以const也被废掉。

下面就是引用了,引用和constant有个很相似的地方,定义的时候就要初始化,初始化以后就不能改(你没见过一个引用初始化了以后又被改成其他对象的引用吧?),而且从内部机制来说,它产生的应该是一个指针(所以类里面才可以定义一个所属的类的引用),既然如此,它也和constant一样不能修改,所以它也不能成为union的成员,不过pointer是可以的

参考:http://topic.csdn.net/t/20040725/17/3208378.html
很多高手
4)
4
class Text
{
public: void bad(const string &parm)const;
private:char *_text;
}

void Text::bad(const string &parm)const
{
_text = parm.c_str(); //Error,修改了成员,由于const所以成员的数值不能修改

for(int ix = 0; ix < parm.size(); ix++)
_text[ix] = parm[ix]; //OK 访问了成员,修改了成员指针指向的内容
}

同样是做修改类成员的操作,为何一个Error一个OK?
废话,const类函数不能修改类内的数据成员,但是可以修改成员指针指向的内容

加了const的成员函数可以理解成
private:char *_text;
->
private:char * const _text;//指针本身不能修改,指向,内容可以
5)没有问题
[解决办法]
1.
  所有静态对象在其他任何对象初始化前初始化,即在程序开始时,他必须在类外部定义.
2.
  有序以前没听说过 今天涨知识了.
3.
  抄袭即可,呵呵(摘自Kenmark:)
  对于union来说,里面所有的对象要保证存在的时候地址相同(这个是union的规则,不要问我为什么),而static成员不会放在非static成员存在的地方,而且static成员要求整个程序运行期间它都存在,这个又和union犯冲,所以当然不该让它存在。

const成员也有这个意思,你想一般const成员都被编译器展开了,哪里还有这个东西存放的地址啊?再说了就算没被展开,他如果被分配在某个地方,这块地方肯定不能更改,这样的话,岂不是union就不能修改了?那还要它有什么用?所以const也被废掉。

下面就是引用了,引用和constant有个很相似的地方,定义的时候就要初始化,初始化以后就不能改(你没见过一个引用初始化了以后又被改成其他对象的引用吧?),而且从内部机制来说,它产生的应该是一个指针(所以类里面才可以定义一个所属的类的引用),既然如此,它也和constant一样不能修改,所以它也不能成为union的成员,不过pointer是可以的
4.
  
  我觉得好象第4题即使去了函数的const修饰符也不行,以为成员_text是non-const的,而.c_str()返回的是一个char const*,这样赋值行吗?

5.
  语法看不出问题.
[解决办法]
我来总结一下:

1。 这个肯定要赋值的,因为既然定义const类型的变量,const是常量,当然要在定义的时候赋值。
2。有序这个概念,C++Primer上面讲过,只是大家没有留意而且也不容易理解,其实可以简单的理解为类似数字类型(如:int),char。。等简单变量,很容易赋值的。因为有些变量是不能一下子给出初值的。
3。Kenmark(fenix) ( 两星(中级)) 相信已经说得很清楚了。
4。为什么_Text = parm.c_str();会错呢?这是因为在定义函数bad的时候有一个const限定,这说明该类中的成员函数是不会有任何修改的,但是_Text = ***这句显然将私有成员值char* _Text 修改了。所以编译是不允许的。如果你去掉bad后面的const限定,应该就没有问题。但是_Text[i] = *** 为什么就可以了呢,这是因为,此时成员变量是char* _Text,只要_Text本身的值没有变就可以,至于,地址里面存放的内容改变是合法的。


5。应该没有任何问题。

读书人网 >C++

热点推荐