Constructors and Destructors in c++

构造函数constructions

构造函数的函数名要和class名一致!!
C++11中,当类中含有不能默认初始化的成员变量时,可以禁止默认构造函数的生成,

myClass()=delete;//表示删除默认构造函数

myClass()=default;//表示默认存在构造函数
关于构造函数的删除
有点复杂了姐妹!

  1. 典型的是禁止使用拷贝构造函数
  2. 、、、、、类似于move函数?
  3. 而关于delete的显式删除,并非局限于成员函数=,由此我们也知default是只局限作用于类的部分成员函数的。于是我们还可用delete来避免不必要的隐式数据类型转换。比如:
class Entity
{
public:
float X,Y;
void Init()
{
X = 0.0f;
Y = 0.0f;
}
void Print()
{
std::cout << X << "," << Y std::endl;
}
};

int main()
{
Entity e;
e.Init();
e.Print();
std::cin.get();

但是这样就意味着必须在class中要有Init函数??
在c++的槽中必须手动设置所有的初始化
在这里插入图片描述
或者是建立一个construction函数

在这里插入图片描述
只有当不写任何构造函数的时候,系统才会自动写不带形参的构造函数!
或者
Entity(float x, float y);

有了指针后

class A
{
 public:
   A(int m,int n)
   {
     v=m;
     p = new int (n);
   }
   ~A() //析构函数
   {
     delete p;
   }
  private:
    int v;
    int *p;
};

拷贝构造函数:copy constructors

//一般系统会提供,但是当用到指针,或者是深拷贝,需要手动写

形参为本类的对象引用,用已经有的数据对象,去构造一个新的对象,使得它们之间的类型是一样的

#include<iostream>
using namespace std;
class CExample
{
private:
    int a;
public:
    //构造函数
    CExample(int b)
    {
        a=b;
        printf("constructor is called\n");
    }
    //拷贝构造函数
    CExample(const CExample & c) //必须得是引用符号!!
    {
        a=c.a;
        printf("copy constructor is called\n");
    }
    //析构函数
    ~CExample()
    {
        cout<<"destructor is called\n";
    }
    void Show()
    {
        cout<<a<<endl;
    }
};
int main()
{
    CExample A(100);
    CExample B=A;
    B.Show(); 
    return 0;
}

  

拷贝构造函数的调用时间:
1.当形参数是类的对象时!

#include<iostream>
using namespace std;
class CExample
{
private:
    int a;
public:
    CExample(int b)
    {
        a=b;
        printf("constructor is called\n");
    }
    CExample(const CExample & c)
    {
        a=c.a;
        printf("copy constructor is called\n");
    }
    ~CExample()
    {
     cout<<"destructor is called\n";
    }
    void Show()
    {
     cout<<a<<endl;
    }
};
void g_fun(CExample c)
{
    cout<<"g_func"<<endl;
}
int main()
{
    CExample A(100);
    CExample B=A;
    B.Show(); 
    g_fun(A);
    return 0;
}

构造函数的初始化列表

构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。例如:

class Entity {
public:
    int a;
    float b;
    //构造函数初始化列表
    Entity(): a(0),b(8.8)
    {}
    //或者是构造函数内部赋值
    Entity()
    {
        a=0;
        b=8.8;
    }
};

上面的俩种构造函数的方式结果都是一样的,上面的例子中两个构造函数的结果是一样的。上面的构造函数(使用初始化列表的构造函数)显式的初始化类的成员;而没使用初始化列表的构造函数是对类的成员赋值,并没有进行显式的初始化。
初始化和赋值对内置类型的成员没有什么大的区别,像上面的任一个构造函数都可以
但是对非内置类型成员变量,为了避免两次构造,推荐使用类构造函数初始化列表。但有的时候必须用带有初始化列表的构造函数:

  • consrt成员或者引用类型的成员,因为const只能初始化,不能赋值
  • 成员类型是没有默认构造函数的类

whole: : whole()
{
data = 0;
}

用形参,构造类的对象成员的私有成员

whole :: whole(int i,int j, int k):
two(i),one(j),data(k) //用形参k初始化了数据data
{ }

析构函数

析构函数也是一种成员函数,它的作用与构造函数完全相反
我们仅仅在主函数退出时看到析构函数被调用
析构函数就是一种在销毁对象时调用的方法,它在函数调用结束的时候才会运行哦!
析构函数的作用:

  • 析构函数中调用的某些初始化代码,想要取消初始化或者销毁析构函数中的开始对象,原因是,不这样做会使内存泄漏!
  • 如果在堆上手动分配了任何类型的内存,需要手动销毁!

其余的下次补充哦!

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下为C++代码实现: ```cpp #include <iostream> #include <string> using namespace std; // 宠物类 class Pet { protected: string name; int age; double weight; public: Pet(string name, int age, double weight) { this->name = name; this->age = age; this->weight = weight; } string getName() { return name; } int getAge() { return age; } double getWeight() { return weight; } void setName(string name) { this->name = name; } void setAge(int age) { this->age = age; } void setWeight(double weight) { this->weight = weight; } virtual string getLifespan() { return "unknown lifespan"; } }; // 狗类 class Dog : public Pet { private: string breed; public: Dog(string name, int age, double weight, string breed) : Pet(name, age, weight) { this->breed = breed; } string getBreed() { return breed; } void setBreed(string breed) { this->breed = breed; } virtual string getLifespan() { if (weight > 100) { return "Approximately 7 years"; } else { return "Approximately 13 years"; } } }; // 岩石类 class Rock : public Pet { public: Rock(string name, int age, double weight) : Pet(name, age, weight) {} virtual string getLifespan() { return "Thousands of years"; } }; // 测试代码 int main() { Pet* pet1 = new Rock("Rocky", 1000, 1000); Pet* pet2 = new Dog("Fido", 3, 80, "Golden Retriever"); cout << pet1->getName() << ", " << pet1->getLifespan() << endl; cout << pet2->getName() << ", " << pet2->getLifespan() << endl; delete pet1; delete pet2; return 0; } ``` 运行结果为: ``` Rocky, Thousands of years Fido, Approximately 13 years ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值