- 关于拷贝构造函数;
1,对于一个类X,如果构造函数的第一个参数是下面四种情况之一:
a) X&
b) const X&
c) volatile X&
d) const volatile X&
且没有其他参数或其他参数都有默认值,那么这个函数是拷贝构造函数.
2,可以允许有下面两个拷贝构造函数同时存在:
- class X {
- public:
- X(const X&);
- X(X&); // OK
- };
3,拷贝构造函数不能由成员函数模板生成;
2,关于strlen()函数:
1 char* c="test"; 2 3 int m=strlen(c); 4 5 cout<<m<<endl; 6 7 char* p=new char[strlen(c)+1]; 8 strcpy(p, c); 9 10 cout<<p<<endl;
11
12 delete []p;
第二行,m = 4; //即统计大小是忽略最后一个空字符' ';
第七行,在申请字符数组空间时,应在strlen()所得值得基础上加1(否则最后第12行的语句会不断出错);(参看P320,p340) ; (关于strncpy()函数参看P459页笔记) ;
第十行,输出为:"test";(引号内);
2,关于构造顺序
1,类成员以其在类中声明的顺序进行构造;
class Base1
{
...
};
class Base2
{
...
};
class SubBase
{
public:
SubBase():base2(), base1()
{
};
protected:
Base1 base1;
Base2 base2;
};
在进行SubBase构造时,进入SubBase的构造函数,执行顺序为首先执行到构造函数的花括号前,接着执行
数据成员的构造(上面为protected后面的部分),最后才执行SubBase构造函数的花括号里面的语句;
2,派生类(即子类)的构造;
派生类的构造总是由基类构造(即初始化)开始;
3,多继承的构造顺序;
1,首先,虚基类的构造函数以它们被继承的顺序进行构造;
2,其次,非虚基类的构造按照它们被继承的顺序进行构造;
3,再次,成员对象的构造按照它们被声明的顺序进行;
4,最后,多继承类自己的构造(即,多继承类自己构造函数花括号里的语句)。
3,Windows系统下,按一次回车键等于先后连续按下连个字符:
: 回车符——回到一行的开头;
: 换行符——跳到下一行;
4,指针间接引用与自增操作
a: sum+= * iptr;
iptr++;
b: sum+= * (iptr ++);
c: sum+= * iptr++;
上面的三条语句等价。原因如下:
i: 后自增运算的优先级排在第一位(高于 间接引用运算符的优先级,第二位);
ii: 后自增运算符返回一个经自身拷贝后得到临时对象;
5,探究C++中while(cin>>str)该判断条件
以下为转载,作者的分析很透彻:
就在我迷茫之时看到了这么一行代码:
/** * @brief The quick-and-easy status check. * * This allows you to write constructs such as * "if (!a_stream) ..." and "while (a_stream) ..." */ operator void *() const { return this ->fail() ? 0 : const_cast <basic_ios*>( this ); } |
也就是说如果 this->fail() 返回 true,这个函数则返回 0。原来问题点的核心在这里,当时提供这个方案就是为了 while(cin>>str )这种判断。
现在的问题在于,什么情况下会调用这个函数?在执行 while (cin >> str) 时进行了(void*)这个转换吗,要验证很简单,看下面这个例子:
#include <iostream> class my_istream { public : operator void * () const { return 0; } }; int main () { my_istream mi; my_istream &mi_ref = mi; do { std::cout << "I am right!" << std::endl; } while (mi_ref); return 0; } |
假如将 operator void * () const 去掉编译器会提示如下错误:
E:TEMP_FILE est_volatilemain.cpp||In function ‘int main()’:|
E:TEMP_FILE est_volatilemain.cpp|18|error: could not convert ‘mi_ref’ to ‘bool’|
||=== Build finished: 1 errors, 0 warnings ===|
Ok,总结:
while (cin >> str) ivec.push_back(str); |
while 判断时,会调用了 operator void*() 这个函数,是否返回 0 取决于 fail 这个函数。当在缓冲区读入数据的时候,如果出现
异常,这些异常通过一些变量记录下来,而这些变量会左右 fail 的返回值。
CTRL+Z -> 引发异常 -> 记录异常 -> fail() 返回true-> operator void*() 返回 0 -> while结束
在 cplusplus.com 中对这个函数的解释这样的:
operator void * () const;
Convert to pointer
A stream object derived from ios can be casted to a pointer. This pointer is a null pointer if either one of the error
flags (failbit or badbit) is set, otherwise it is a non-zero pointer.
The pointer returned is not intended to be referenced, it just indicates success when none of the error flags are set.
(可以看出和我的理解是一致的)
6,关于数据类型bool;
a,ture , false;
b,当整型对待(“1“);
bool found = ture;
int a;
a = 1 + fount;
c,指针可以当做bool对象进行操作;
7,关于间接访问、自增相遇时的先后顺序问题;
i, (* a ++) : 先后自增再间接访问;后自增的优先级高于间接访问;
ii, (* ++ a) : 先前自增再间接访问;
iii, (++ * a) : 先间接访问再前自增;