const用法总结以及构造函数、析构函数、拷贝构造函数的深入剖析
2013-05-14 13:36
483 查看
1. 用const时候,通常需要初始化:
3. 用const来修饰函数参数:
为了防止上述的fun1() = a;和fun3(b) = a;这样的语句,就采用const修饰返回值(其实,我有点纳闷:哪个傻瓜程序员会这么调用函数?),改正后的程序为:
现在,一切都明白了吧!在上面的程序中,我们注意到有返回引用的情况,下面来看看引用是如何返回的:
constructor
destructor
constructor
copy constructor
destructor
destructor
constructor
destructor
constructor
copy constructor
destructor
destructor
constructor
destructor
由此可见,对于ADT数据类型而言,用引用做函数参数或返回值,都能提高效率。
#include<iostream> using namespace std; int main() { int const i; // error C2734: 'i' : const object must be initialized if not extern return 0; }
#include<iostream> using namespace std; int main() { int i = 1; const int j = i; // 只能在初始化时赋值 i = j; //j = i; 此语句错误 return 0; }2. 如果涉及指针,会稍微复杂一点:
#include<iostream> using namespace std; int main() { int i = 1; const int *p = &i; // 星在const右,表示*p不能直接改变,但p可变 // *p = 2; 错误:不能直接改变 i = 2; // 正确: *p不能变,但i可以变 int j = 3; int *q = &j; p = q; // 正确: p可变 return 0; }
#include<iostream> using namespace std; int main() { int i = 1; int const*p = &i; // 星在const右,表示*p不能直接改变,但p可变 // *p = 2; 错误:不能直接改变 i = 2; // 正确: *p不能变,但i可以变 int j = 3; int *q = &j; p = q; // 正确: p可变 return 0; }
#include<iostream> using namespace std; int main() { int i = 1; int *const p = &i; // 星在const左,表示p不能改变,但*p可直接变 *p = 2; i = 2; int j = 3; int *q = &j; //p = q; 错误:p不能变 return 0; }总结:星在const左,p不能改变;星在const右,*p不能直接改变;星在两个const中间,p不能改变,*p也不能直接改变。
3. 用const来修饰函数参数:
#include<iostream> using namespace std; int increase(const int x) { // x = x + 1; 错误:x不能改变 return x; } int main() { return 0; }
#include<iostream> using namespace std; void fun(const int *p) { p = NULL; // 正确 // *p = 0; 错误:不能直接改变*p } int main() { return 0; }
#include<iostream> using namespace std; void fun(const int &x) { // x = x + 1; 错误:x不能改变 } int main() { return 0; }
#include<iostream> using namespace std; class A{}; // fun1比fun2的效率要高 void fun1(const A &x) // 不存在对象拷贝 { } A fun2(const A x) // 存在对象拷贝 { return x; } int main() { A a; fun1(a); a = fun2(a); return 0; }4. 用const修饰函数的返回值
#include<iostream> using namespace std; const int fun(int x) // 这种情况下,const没有任何作用 { x = x + 1; return x; } int main() { int a = 1; int b = fun(a); return 0; }
#include<iostream> using namespace std; const char *fun(char str[]) // 返回指针的类型是 const char * 类型的 { return str; } int main() { char s[] = "hello"; // char *p = fun(s); 错误 const char *p = fun(s); cout << p << endl; return 0; }
#include<iostream> using namespace std; class A{}; A fun1() { A x; return x; } A *fun2(A *q) { return q; } A &fun3(A &x) { return x; } int fun4() { int i = 1; return i; } int main() { A a, b, *p; fun1() = a; // 语法上正确,但风格不好 // fun2(p) = NULL; // 语法上错误 fun3(b) = a; // 语法上正确,但风格不好 int i; // fun4() = i; // 语法上错误 return 0; }
为了防止上述的fun1() = a;和fun3(b) = a;这样的语句,就采用const修饰返回值(其实,我有点纳闷:哪个傻瓜程序员会这么调用函数?),改正后的程序为:
#include<iostream> using namespace std; class A{}; const A fun1() { A x; return x; } const A *fun2(A *q) // 可以不需要const, 但加上后,肯定不错 { return q; } const A &fun3(A &x) { return x; } const int fun4() // 可以不需要const,但加上后,肯定不错 { int i = 1; return i; } int main() { A a, b, *p; // fun1() = a; // 语法上错误 // fun2(p) = NULL; // 语法上错误 // fun3(b) = a; // 语法上错误 int i; // fun4() = i; // 语法上错误 return 0; }
现在,一切都明白了吧!在上面的程序中,我们注意到有返回引用的情况,下面来看看引用是如何返回的:
#include <iostream> using namespace std; int &fun(int &x) { return x; } int main() { int a = 1; int &b = fun(a); // 注意初始化引用的方法 cout << a << endl; // 1 cout << b << endl; // 1 b = 2; cout << a << endl; // 2 cout << b << endl; // 2 b = 3; cout << a << endl; // 3 cout << b << endl; // 3 return 0; }一切都明白了。最后欣赏几个程序,补补C++的基本知识:
#include <iostream> using namespace std; class A { public: // 构造函数 A() { cout << "constructor" << endl; } // 析构函数 ~A() { cout << "destructor" << endl; } // 拷贝构造函数 A(A &) { cout << "copy constructor" << endl; } }; void fun(A a) { } int main() { A a; return 0; }结果为:
constructor
destructor
#include <iostream> using namespace std; class A { public: // 构造函数 A() { cout << "constructor" << endl; } // 析构函数 ~A() { cout << "destructor" << endl; } // 拷贝构造函数 A(A &) { cout << "copy constructor" << endl; } }; void fun(A a) { } int main() { A a; fun(a); return 0; }结果为:
constructor
copy constructor
destructor
destructor
#include <iostream> using namespace std; class A { public: // 构造函数 A() { cout << "constructor" << endl; } // 析构函数 ~A() { cout << "destructor" << endl; } // 拷贝构造函数 A(A &) { cout << "copy constructor" << endl; } }; void fun(A &a) { } int main() { A a; fun(a); return 0; }结果为:
constructor
destructor
#include <iostream> using namespace std; class A { public: // 构造函数 A() { cout << "constructor" << endl; } // 析构函数 ~A() { cout << "destructor" << endl; } // 拷贝构造函数 A(A &) { cout << "copy constructor" << endl; } }; A fun(A &a) { return a; } int main() { A a; fun(a); return 0; }结果为:
constructor
copy constructor
destructor
destructor
#include <iostream> using namespace std; class A { public: // 构造函数 A() { cout << "constructor" << endl; } // 析构函数 ~A() { cout << "destructor" << endl; } // 拷贝构造函数 A(A &) { cout << "copy constructor" << endl; } }; A &fun(A &a) { return a; } int main() { A a; fun(a); return 0; }结果为:
constructor
destructor
由此可见,对于ADT数据类型而言,用引用做函数参数或返回值,都能提高效率。
相关文章推荐
- 总结c++类的构造函数 拷贝构造函数 析构函数 赋值运算符重载的特点以及函数调用顺序
- 深入C++中构造函数、拷贝构造函数、赋值操作符、析构函数的调用过程总结
- 深入C++中构造函数、拷贝构造函数、赋值操作符、析构函数的调用过程总结
- 深入C++中构造函数、拷贝构造函数、赋值操作符、析构函数的调用过程总结
- 从零开始学C++之构造函数与析构函数(二):初始化列表(const和引用成员)、拷贝构造函数
- 从零开始学C++之构造函数与析构函数(二):初始化列表(const和引用成员)、拷贝构造函数
- C++ 学习总结(十)——C++类与对象,及构造函数,析构函数,拷贝构造函数
- 从零开始学C++之构造函数与析构函数(二):初始化列表(const和引用成员)、拷贝构造函数
- C++的6大成员函数,构造函数(初始化列表),析构函数,拷贝构造函数,运算符重载,const成员函数
- c++ 构造函数 拷贝构造函数 析构函数 总结
- 字符串strcpy函数的实现,以及字符串string的实现,编写构造函数,拷贝构造函数,赋值函数,析构函数
- 总结笔记-c++成员变量、构造函数以及析构函数的执行顺序
- 类中的构造函数与析构函数、函数重载以及this指针的总结
- 深入理解构造函数和析构函数以及父类和子类的部分关系
- 关于C++中的构造函数、拷贝构造函数、析构函数的总结
- C#学习笔记整理_深入剖析构造函数、析构函数
- 拷贝构造函数,深拷贝,大约delete和default相关业务,explicit,给定初始类,构造函数和析构函数,成员函数和内联函数,关于记忆储存,默认参数,静态功能和正常功能,const功能,朋友
- C++四种强制类型转换符功能以及用法总结(dynamic_cast,const_cast,static_cast,reinterpret_cast)
- 从零开始学C++之构造函数与析构函数(二):初始化列表(const和引用成员)、拷贝构造函数
- 20170825_string构造函数、析构函数、拷贝构造函数以及重载赋值运算符