类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数

// person.h
#ifndef _PERSON_H_
#define _PERSON_H_ class Person{
public :
Person();
Person(int myage, char *myname);
Person(const Person &a);
Person& operator=(const Person& other);
~Person(void); void set_age(int myage);
int get_age(void) const;
void set_other_age(Person &a, int b);
void print() const; private:
int age;
char *name;
}; #endif
// person.cc
#include "person.h" #include <iostream>
#include <stdio.h>
#include <string.h> using namespace std; Person::Person():age(), name(NULL)
{
//nothing
cout<<"no param construct!"<<endl;
} Person::Person(int myage, char *myname)
{
age = myage;
if(myname != NULL){
name = new char[strlen(myname) + ];
this->print();
strcpy(name, myname);
}
cout<<"param construct!"<<endl;
} Person::Person(const Person &a)
{
cout <<"copy constructor!"<<endl;
if(a.name != NULL){
name = new char[strlen(a.name)+];
this->print();
strcpy(name, a.name);
age = a.age;
} else {
name = NULL;
age = ;
}
}
Person& Person::operator=(const Person &a)
{
cout <<"= constructor!"<<endl;
if(&a == this){
return *this;
} if(name != NULL){
delete [] name;
name = NULL;
}
if(a.name != NULL){
name = new char[strlen(a.name)+];
this->print();
strcpy(name, a.name);
age = a.age;
} else {
name = NULL;
age = ;
} return *this;
} Person::~Person()
{
if(NULL != name){
delete [] name;
name = NULL;
}
cout<<"destructor!"<<endl;
}
void Person::set_age(int myage)
{
age = myage;
} int Person::get_age(void) const
{
return age;
} void Person::set_other_age(Person& a, int b)
{
a.age = b;
//a.set_age(b);
} void Person::print() const
{
if(name != NULL)
cout <<"value:" << name;
cout<< " name=" << static_cast<void*> (name) << endl;
}
// main.cc
#include "person.h" #include <iostream>
using namespace std; int main(int argc, char *argv[])
{
Person a(, "xiaohhhhh");
Person b(, "mingttttt");
Person m; m = b;
a.print();
b.print();
m.print(); Person n(, "qing");
b=n;
a=n;
m=n;
a.print();
b.print();
m.print(); return ;
}

构造函数、析构函数和赋值函数是类最重要的函数,被称为The Big Three。
与其他成员函数相比,The big three特殊之处在于,如果代码中没有提供这些函数的实现,C++编译器自动合成缺省的函数实现。
有指针成员变量的类一定要提供The Big Three的实现,即使没有指针变量,作为良好的编程习惯也应该提供The Big Three的实现。

1. 构造函数

和类同名,无返回值,用来初始化类的对象。
构造函数可重载。
编译器提供默认无参构造函数,若声明新的,则采用新的构造函数。一般多应创建一个无参的构造函数,因为创建了有参构造函数后,默认的无参构造函数被覆盖。
构造函数在对象创建后马上调用。
Person a; //调用无参构造函数
Person a(20, "Xiaoming"); //调用两参构造函数
Person(int age=0, const char *name = NULL);构造函数,相当于创建无参或两参构造函数。

2.拷贝构造函数

Person(const Person &a);
如果没有提供拷贝构造函数,编译器会默认提供一个(执行逐个成员初始化,将新对象初始化为原对象的副本,这里的逐个是指编译器将现有对象的每个非static成员,依次复制到正在创建的对象)。
如果类有指针成员变量或类数据成员管理资源(如打开一个文件),默认构造函数并不会自动分配指针所指向的空间(默认构造函数仅提供浅拷贝),需要添加拷贝构造函数实现深拷贝。
默认拷贝构造函数实现浅拷贝:指针成员变量指向同一存储区域,而不是重新分配区域再赋值(深拷贝)。
如果想禁止一个类的拷贝构造,需要将拷贝构造函数声明为private。

3. 析构函数

析构函数不可重载。
类名前加~的函数,无参数,无返回值。
先调用析构函数->后销毁对象。
默认的析构函数不会释放指针成员变量分配的内存区域,可能造成内存泄露。有指针成员变量时必须实现析构函数。

4. 赋值函数

Person& operator=(const Person& other);
基本与拷贝构造等价。如果想禁止一个类的赋值函数,需要将拷贝构造函数声明为private。
Person b=a; //拷贝构造函数
Person b;
b = a; //赋值函数 operator=

5. 构造函数的初始化列表

const变量必须用初始化列表进行初始化。
Person():age(10), name(NULL)中":age(10),name(NULL)"为初始化列表。

6. set_other_age()同一类的不同对象可以访问其他对象的私有数据。

7. this指针

每个成员方法都包含一个隐藏参数this,this是一个对象的指针,指向调用函数的对象。
判断自赋值:

if(this == &a){
return *this;
}

CPP_类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数的更多相关文章

  1. [Reprint]C++友元函数与拷贝构造函数详解

    这篇文章主要介绍了C++友元函数与拷贝构造函数,需要的朋友可以参考下   一.友元函数 1.友元函数概述: (1)友元函数是定义在一个类外的普通函数.友元函数和普通函数的定义一样;在类内必须将该普通函 ...

  2. 《剑指offer》面试题1:为类CMyString添加赋值运算符函数——C++拷贝构造函数与赋值函数

    题中已给出CMyString的类定义,要求写赋值运算符函数. #include<iostream> #include<cstring> using namespace std; ...

  3. 【c++ primer, 5e】构造函数 & 拷贝、赋值和析构

    [构造函数] 1.构造器就是创建对象时被调用的代码. 2.如果没有自定义构造器,那么编译器将自动合成一个默认的无参构造器. 3.自定义的构造器不允许加const,所创建const的对象只有在构造器代码 ...

  4. C++构造函数 & 拷贝构造函数 & 派生类的构造函数 & 虚继承的构造函数

    构造函数 ,是一种特殊的方法 .主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 .特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数 ...

  5. C++语言债券系列之十一——友元函数和拷贝构造函数

    1.好友功能 (1)友元函数类的普通功能外定义. 定义友元函数和相同的正常功能.在类必须声明的正常功能为好友. (2)友元函数不是一个成员函数. 你不能反对打电话.但直接调用:友元函数访问类的公共.p ...

  6. 使用new分配内存的类需要自己定义拷贝构造函数

    13.22 假定我们希望HasPtr的行为像一个值.即,对于对象所指向的string成员,每个对象都有一份自己的拷贝. #include<iostream> #include<str ...

  7. C++类中函数(构造函数、析构函数、拷贝构造函数、赋值构造函数)

    [1]为什么空类可以创建对象呢? 示例代码如下: #include <iostream> using namespace std; class Empty { }; void main() ...

  8. C++雾中风景6:拷贝构造函数与赋值函数

    在进行C++类编写的过程之中,通常会涉及到类的拷贝构造函数与类的赋值函数.初涉类编写的代码,对于两类函数的用法一直是挺让人困惑的内容.这篇文章我们会详细来梳理拷贝构造函数与赋值函数的区别. 1.调用了 ...

  9. C++中构造函数,拷贝构造函数和赋值函数的区别和实现

    C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法.下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函数 构造函数是一种特殊的类成员函数,是当创建一个类的对象 ...

随机推荐

  1. oracle中exists和in的比较

    exists 是Oracle sql中的一个函数.表示是否存在符合某种条件的记录.如 select * from A,B where A.id=B.id and exists (SELECT * FR ...

  2. Oracle数据库中number类型在java中的使用

    1)如果不指定number的长度,或指定长度n>18 id number not null,转换为pojo类时,为java.math.BigDecimal类型 2)如果number的长度在10 ...

  3. JSON.toJSONString中序列化空字符串遇到的坑

    前言 最近在做系统Bug修复时遇到了一个问题,调用其他服务时传递的参数和自己预先的不一致,例如Map中有10条记录,然后使用JSON.toJSONString 包装后进行网络传递,但是通过调试发现接收 ...

  4. postgres json

    https://www.postgresql.org/docs/9.6/static/functions-json.html Search Documentation:  Home → Documen ...

  5. 【Unity】6.4 Transform--移动、旋转和缩放游戏对象

    分类:Unity.C#.VS2015 创建日期:2016-04-20 一.简介 Unity引擎提供了丰富的组件和类库,为游戏开发提供了非常大的便利,熟练掌握和使用这些API,对于游戏开发的效率提高很重 ...

  6. 深入理解Linux内核-进程调度

    1.什么时候进行进程切换 调度策略目标:1.进程响应尽量快:2.后台作业吞吐量尽量高:3.尽可能避免进程饥饿:4.低优先级和高优先级进程需要尽量调和. 调度策略:决定什么时候选择什么进程运行的规则.基 ...

  7. 趣味讲解:移动互联网 VS 传统互联网

    趣味讲解:移动互联网 VS 传统互联网 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转 ...

  8. <![CDATA[]]>和转义字符

    被<![CDATA[]]>这个标记所包含的内容将表示为纯文本,比如<![CDATA[<]]>表示文本内容“<”. 此标记用于xml文档中,我们先来看看使用转义符的情 ...

  9. 使用tar命令解压的时候报错not in gzip format

    使用tar命令解压一个xx.tar.gz压缩包的时候报错not in gzip format,后用file xx.tar.gz查看一下格式发现是html document text格式的...

  10. javascript基础拾遗(四)

    1.什么是闭包 正常函数,执行完毕后相关的参数,变量就释放掉了. 当一个函数的返回值是另一个函数时,该函数的相关参数和变量都会保存在返回的函数中,这种结构叫做闭包. 2.示例 计算数组和 functi ...