C++复制构造函数,类型转换构造函数,析构函数,引用,指针常量和常量指针
复制构造函数
形如className :: className(const &) / className :: className(const className &)后者能以常量对象作为参数
如不写复制构造函数,则编译器默认提供,为了完成对象的复制功能
它起作用有三个工作环境:
1.一个对象初始化另一个同类的对象
Simple c2(c1);
Simple c2 = c1;//初始化
2.如果某函数有一个参数是类的一个对象,那么该函数被调用时,类的复制构造函数被调用
Simple A
{
pbulic:
A(){};
A(A & a)
{
cout<<.....<<endl;
}
};
void Fun(A a1){}
int main()
{
A a;
Fun(a);//.....
return ;
}
3.如果函数的返回值是类的对象时,则函数返回是,类的复制构造函数被调用
class Simple
{
pbulic:
int x;
Simple(int n){x = n;};
Simple(const Simple & a)
{
x = a.x;
cout<<"Copy constructor called"<<endl;
}
};
Simple Fun()
{
Simple b();
return b;//作为复制构造函数的参数
}
int main()
{
cout<<Fun().x<<endl;// Copy constructor called 100
return ;
}
注意:对象间的赋值不导致复制构造函数的调用
A c1,c2;
c2 = c1 ;//不会调用
A C3(C1);//这是初始化操作,会调用赋值构造函数
在函数参数列表中,为节省开销,不引发复制构造函数的调用,使用ClassName & 引用类型为参数,
又为了确保实参值不变,再在引用前加上const关键字。复制构造函数往往加const和&,具体可以点这里
类型转换构造函数
它的目的是实现类型的自动转换,并且只有一个参数。当需要的时候,编译系统会自动调用转换构造函数,建立
一个无名的临时对象(或临时变量)。
class Complex
{
public:
double real, imag;
Complex( int i)
{//类型转换构造函数
cout << "IntConstructor called" << endl;
real = i; imag = ;
}
Complex(double r,double i) {real = r; imag = i; }
};
int main ()
{
Complex c1(,);
Complex c2 = ;
c1 = ; // 9被自动转换成一个临时Complex对象
cout << c1.real << "," << c1.imag << endl;
return ;
}
class Complex
{
public:
double real, imag;
explicit Complex( int i)
{//显式类型转换构造函数
cout << "IntConstructor called" << endl;
real = i; imag = ;
}
Complex(double r,double i) {real = r; imag = i; }
};
int main ()
{
Complex c1(,);
Complex c2 = Complex();
c1 = ; // error, 9不能被自动转换成一个临时Complex对象
c1 = Complex() //ok
cout << c1.real << "," << c1.imag << endl;
return ;
}
析构函数:~类名(){}
它没有返回值和参数,一个类对应一个析构函数,在类的对象消亡时自动调用,也可以手动调用进行对象消亡的善后工作。如果懒的去写,编译器自动会生成缺省析构函数,但是什么也不做,如果写了,就不自动生成了。
class Simple
{
private :
char * p;
public:
Simple()
{
p = new char[];
}
~ Simple () ;
};
Simple ::~ Simple()
{
delete [] p;
}
在对一个对象进行delete时,调用一次析构函数,在delete[]对象数组时,会调用n次析构函数,取决于数组大小。此外:
class CMyclass
{
public:
~CMyclass() { cout << "destructor" << endl; }
};
CMyclass obj;
CMyclass fun(CMyclass sobj )
{ //参数对象消亡也会导致析
//构函数被调用
return sobj; //函数调用返回时生成临时对象返回
}
int main()
{
obj = fun(obj); //函数调用的返回值(临时对象)被
return ; //用过后,该临时对象析构函数被调用
}
//destructor形参对象消亡
//destructor临时对象消亡
//destructor全局对象消亡
new出来的对象或对象数组,不delete就不会消亡,就不会调用析构函数!!不是new出来的,则在生命期结束会自动调用
关于引用:引用是C++有的,C所没有的,标志为 &,即C的取地址符。它的声明为这样
int n = ;
int & r = n; //r为 int & 类型
其中r和n指向同一片地址空间 ,对 r和n的修改都会改变原来是4的那个值,相当于为n取了个别名r
在定义引用时一定要将其初始化成引用某个变量。并且之后不会引用别的变量
只能引用变量,不能引用常量和表达式
一个简单而又形象的,见得次数很多的例子:交换元素
void swap( int * a, int * b)
{
int tmp;
tmp = * a;
* a = * b;
* b = tmp;
}
int n1, n2;
swap(& n1,& n2) ; // n1,n2的值被交换
//用了引用
void swap( int & a, int & b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
}
int n1, n2;
swap(n1,n2) ; // n1,n2的值被交换
//en ..交换还可以这样写,当然远不如swap(a,b)写的快哈
int a = ;
int b = ;
a = a + b;
b = a - b;
a = a - b;
cout<<a<<" "<<b<<endl;
a = a ^ b;
b = a ^ b;
a = a ^ b;
cout<<a<<" "<<b<<endl;
引用还可以作为函数的返回值
int n = ;
int & SetValue()
{
return n;
}
int main()
{
SetValue() = ;
cout << n;return ;
} //输出: 40
关于常引用:
int n;
const int & r = n;
r = 10;//error 不能通过常引用r改变n的值
n = 30;//n的值可以变化
const T & 和T & 是不同的类型!!!
T & 类型的引用或T类型的变量可以用来初始化const T & 类型的引用。
int n = 8;
int & r1 = n;
const int r2 = r1;//初始化const T & 类型的引用。
const T 类型的常变量和const T & 类型的引用则不能用来初始化T &类型的引用,
除非进行强制类型转换
常量指针:
//1.
int n,m
const int * p = n;//常量指针
*p = //error 不可以通过修改常量指针修改指向的内容
n = ;//ok
p = & m;//ok 常量指针可以指向别的内容 //2.不可以把常量指针赋值给非常量指针(强转可以),反之可以
const int * p;
int * p2;
p1 = p2; //ok
p2 = p1; //error
p2 = (int * ) p1; //ok,强制类型转换
指针常量:
int a,b;
int const *p = & a;
* p = ;//通过指针修改所指向的内容,ok
p = & b;//error 不可更改所指向的地址
这两个不要搞混淆了。。。。
简单的记忆,抓住第一个是常量在前,就意味着整个后面的地址内容是个常量,不可以通过指针去修改它,但是指向谁是可以变的;指针常量,这个常量在指针后面,表明这个指针所指向的地址不能变了,但你可以用它修改地址所对应的内容。。
动态内存分配:
变量: int * px = new int; //大小为sizeof(int)
数组: int * pn = new int[20];
释放动态分配的内存:
int * px = new int;
delete px;//只能删除一次
//数组
int * pn = new int[20];
delete [] pn;
C++复制构造函数,类型转换构造函数,析构函数,引用,指针常量和常量指针的更多相关文章
- C++类构造函数、拷贝构造函数、复制构造函数、复制构造函数、构造函数显示调用和隐式调用
一. 构造函数是干什么的 class Counter { public: // 类Counter的构造函数 // 特点:以类名作为函数名,无返回 ...
- C++11新特性之0——移动语义、移动构造函数和右值引用
C++引用现在分为左值引用(能取得其地址)和 右值引用(不能取得其地址).其实很好理解,左值引用中的左值一般指的是出现在等号左边的值(带名称的变量,带*号的指针等一类的数据),程序能对这样的左值进行引 ...
- 《挑战30天C++入门极限》C++类对象的复制-拷贝构造函数
C++类对象的复制-拷贝构造函数 在学习这一章内容前我们已经学习过了类的构造函数和析构函数的相关知识,对于普通类型的对象来说,他们之间的复制是很简单的,例如: int a = 10; int ...
- 构造函数constructor 与析构函数destructor(五)
我们知道当调用默认拷贝构造函数时,一个对象对另一个对象初始化时,这时的赋值时逐成员赋值.这就是浅拷贝,当成员变量有指针时,浅拷贝就会在析构函数那里出现问题.例如下面的例子: //test.h #ifn ...
- 类型转换构造函数 及使用explicit避免类型自动转换------新标准c++程序设计
类型转换构造函数: 除复制构造函数外,只有一个参数的构造函数一般可以称作类型转换构造函数,因为这样的构造函数能起到类型自动转换的作用.例如下面的程序: #include<iostream> ...
- C++转换构造函数与类型转换构造函数
转换构造函数: 转换构造函数的只有一个形参: Student(float s) { score = s; age = ; } 如果已经在上面定义了构造函数: Student(); //建立对象c1,由 ...
- 构造函数constructor 与析构函数destructor(二)
(1)转换构造函数 转换构造函数的定义:转换构造函数就是把普通的内置类型转换成类类型的构造函数,这种构造函数只有一个参数.只含有一个参数的构造函数,可以作为两种构造函数,一种是普通构造函数用于初始化对 ...
- python中的构造函数和构造函数和析构函数的作用
构造函数和构造函数和析构函数都属于python中的特殊方法 其中的“__del__”就是一个析构函数了,当使用del 删除对象时,会调用他本身的析构函数,另外当对象在某个作用域中调用完毕,在跳出其作用 ...
- C++ 引用计数技术及智能指针的简单实现
一直以来都对智能指针一知半解,看C++Primer中也讲的不够清晰明白(大概是我功力不够吧).最近花了点时间认真看了智能指针,特地来写这篇文章. 1.智能指针是什么 简单来说,智能指针是一个类,它对普 ...
随机推荐
- Linux_CentOS软件安装调试 源代码包编译安装和 二进制包配置
Linux 下源代码(C 语言)如何编译(安装) 1. 先安装源代码编译的软件 gcc,make,openssl 如下: yum install -y gcc make gcc-c++ openssl ...
- 【FreeMarker】FreeMarker快速入门(一)
什么是 FreeMarker FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具. 它不是面向最终用户 ...
- spring 使用@Bean装配Bean
通过@Component装配Bean,但是@Component只能注解在类上,不能注解到方法上.对于Java而言,大部分的开发都需要引入第三方的包(jar文件),而且往往并没有这些包的源码,这时候将无 ...
- bootstrap 自带字体颜色
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- idea能用下划线替换红色报错吗?我色弱,用idea简直太痛苦了
看看下图的idea,如果某个类的包路径没有引进来,使用颜色来提示,这对于色弱的程序员简直是一种折磨,有没有可以改成eclipse的那种报错提示方式? 个人感觉idea真的没有eclipse友好,也许是 ...
- ecshop中常用的sql语句
1.获取单条记录 $row = $GLOBALS['db']->getRow($sql); 2.获取单一字段 $row = $GLOBALS['db']->getOne($sql); 查询 ...
- Windows 2016 服务器安全配置和加固
最近一个项目需要使用Windows服务器,选择安装了最新版的Windows 2016,上一次使用Windows服务器还是Windows 2003系统,发现变化还是挺多的,依次记录下来以备后面查阅. 目 ...
- 【计算机视觉】基于Shading Model(对光照变化一定不变性)的运动目标检测算法
光照模型(Shading Model)在很多论文中得到了广泛的应用,如robust and illumination invariant change detection based on linea ...
- idea设置项目【非springboot项目】热部署
1.首先打开Edit Configurations 或者 2.添加的项目一定是war: exploded,而不是war 3.server这边,On 'Update' action选Redeploy,O ...
- 《ucore lab4》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1:分配并初始化一个进程控制块 题目 alloc_proc函数(位于kern/process/proc.c中) 负责分配并返回一个新的str ...