C++中你不知道的语法

来源:互联网 发布:互联网新闻数据分析 编辑:程序博客网 时间:2024/05/29 16:28

传构造函数,不会引起拷贝构造函数的调用

当传一个一个已经构造好的对象时,

[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <stdio.h>  
  3. #include <vector>  
  4. #include <algorithm>  
  5. using namespace std;  
  6. class Foo  
  7. {  
  8.     public:  
  9.     Foo(){cout << "ctr" << endl;}  
  10.     ~Foo(){cout << "de-ctr" << endl;}  
  11.     Foo(const Foo& rhs)  
  12.     {  
  13.         cout << "copy-ctr" << endl;  
  14.     }  
  15.     Foo& operator=(const Foo& rhs)  
  16.     {  
  17.         cout << "operator=" << endl;  
  18.     }  
  19. };  
  20. void f(Foo f)  
  21. {  
  22. }  
  23. int main()  
  24. {  
  25.     Foo a;  
  26.     f(a);  
  27.     return 0;  
  28. }  

结果为:

[c-sharp] view plaincopy
  1. ctr  
  2. copy-ctr  
  3. dectr  
  4. dectr  

当传参时构造对象时,

[c-sharp] view plaincopy
  1. int main()  
  2. {  
  3.     f(Foo());  
  4.     return 0;  
  5. }  

结果就变成:

[c-sharp] view plaincopy
  1. ctr  
  2. dectr  


引申:

同理在模板类当中,同样成立,你不要把它看成一个函数调用了,它是也一个临时对象。如下:

[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <stdio.h>  
  3. #include <vector>  
  4. #include <algorithm>  
  5. using namespace std;  
  6. template <typename T>  
  7. class print  
  8. {  
  9.     public:  
  10.     print(){cout << "ctr" << endl;}  
  11.     ~print(){cout << "de-ctr" << endl;}  
  12.     print(const print<T>& rhs)  
  13.     {  
  14.         cout << "copy-ctr" << endl;  
  15.     }  
  16.     print<T>& operator=(const print<T>& rhs)  
  17.     {  
  18.         cout << "operator=" << endl;  
  19.     }  
  20.     void operator()(const T& elem)  
  21.     {  
  22.         cout << elem << endl;  
  23.     }  
  24. };  
  25. void f(print<int> f)  
  26. {  
  27.     f(1);  
  28. }  
  29. int main()  
  30. {  
  31.     f(print<int>());  
  32.     return 0;  
  33. }  

 

new操作符-空间还可以这样分配

[cpp] view plaincopy
  1. #include <iostream>  
  2. using namespace std;  
  3. class Foo  
  4. {  
  5. public:  
  6.     int i;  
  7.     Foo(){ cout << "ctr" << endl;}  
  8.     ~Foo(){cout << "dectr" << endl;}  
  9.     Foo(const Foo& rhs)  
  10.     {  
  11.         i = rhs.i;  
  12.         cout << "copy-ctr" << endl;  
  13.     }  
  14.     Foo& operator=(const Foo& rhs)  
  15.     {  
  16.         i = rhs.i;  
  17.         cout << "operator=" << endl;  
  18.         return *this;  
  19.     }  
  20. };  
  21. int main()  
  22. {  
  23.     //test1  
  24.     Foo* p = new Foo();  
  25.     p->i = 1;  
  26.     Foo f;  
  27.     f.i = 2;  
  28.     Foo *p2 = new(p) Foo(f);  
  29.     cout << p2->i << endl;  
  30.     p2->i = 3;  
  31.     cout << p->i;  
  32.     cout << endl;  
  33.     delete p2;  
  34.     //delete p; //肯定会出错,因为重复删除了同一个空间  
  35.     cout << endl;  
  36.     //test2  
  37.     char* str = new char[sizeof(Foo)];  
  38.     Foo *p3 = new(str) Foo(f);  
  39.     cout << p3->i << endl;  
  40.     return 0;  
  41. }  

在上例中,Foo *p2 = new(p) Foo(f); 意思是说在对象p的空间上,构造一个跟f一样的对象。

而Foo *p3 = new(str) Foo(f);是在一个字符串的空间上构造的。

 

下面两个函数实际上事一样的,你知道么?

[cpp] view plaincopy
  1. typedef void (*func)();  
  2. func set_handler1(func f)  
  3. {  
  4.     func tmp = f;  
  5.     return tmp;  
  6. }  
  7. void (* set_handler2(void (*f)()))()  
  8. {  
  9.     func tmp = f;  
  10.     return tmp;  
  11. }  

 

对象的隐式构造

[cpp] view plaincopy
  1. //隐式构造  
  2. class Foo  
  3. {  
  4. public:  
  5.     Foo(int i){cout << "ctr" << endl;}  
  6.     Foo(const Foo& f){cout << "copy-ctr" << endl;}  
  7.     Foo& operator=(const Foo& f){cout << "operator=" << endl; return *this;}  
  8.     ~Foo(){cout << "dectr" << endl;}  
  9. };  
  10.   
  11. class Test  
  12. {  
  13. public:  
  14.     Foo f()  
  15.     {  
  16.         return 1;  
  17.     }  
  18. };  
  19.   
  20. void test()  
  21. {  
  22.     //1  
  23.     Test t;  
  24.     Foo f1 = t.f();  
  25.   
  26.     //2  
  27.     Foo f2 = 1;  
  28. }  
  29. int main()  
  30. {  
  31.     test();   
  32.     return 0;  
  33. }  

这是可以运行的,也是C++支持的.

如果你不想让它这样趁你不注意,偷偷摸摸的构造了对象, 你可以在构造函数前面加上explicit.

[c-sharp] view plaincopy
  1. class Foo  
  2. {  
  3. public:  
  4.     explicit Foo(int i){cout << "ctr" << endl;}  
  5.     Foo(const Foo& f){cout << "copy-ctr" << endl;}  
  6.     Foo& operator=(const Foo& f){cout << "operator=" << endl; return *this;}  
  7.     ~Foo(){cout << "dectr" << endl;}  
  8. };  

这时,就会报错.

 

预编译指令的妙处

[cpp] view plaincopy
  1. #define _B(x) #x  
  2. #define PRINT(x, y, z) PRINT_##z(x,y)  
  3. class BigInteger  
  4. {  
  5. public:  
  6.     BigInteger(const char *){}  
  7. };  
  8.   
  9. void PRINT_MAX(int i, int j)  
  10. {cout << (i>j?i:j) << endl;}  
  11.   
  12. void PRINT_MIN(int i, int j)  
  13. {cout << (i>j?j:i) << endl;}  
  14.   
  15. void test(int i, int j)  
  16. {  
  17.     //1  
  18.     BigInteger b = _B(12122222222222222222222222);  
  19.     cout << _B(12122222222222222222222222) << endl;  
  20.   
  21.     //2  
  22.     PRINT(i, j, MAX);  
  23.     PRINT(i, j, MIN);  
  24. }  
  25.   
  26. int main()  
  27. {     
  28.     test(1, 2);  
  29.     return 0;  
  30. }  

你猜猜结果?

 

上面的#x表示把x生成成为一个字符串.

a##b是把ab连接成一个字符串.

上面的两个用法和用途,相信可以让你感到妙不可言.

结果:

[c-sharp] view plaincopy
  1. 12122222222222222222222222  
  2. 2  
  3. 1  
  4. 请按任意键继续. . .  
原创粉丝点击