C++中类对象创建的几种方式

  • 类是创建对象的模板,一个类可以创建多个对象,每个对象都是类类型的一个变量
  • 创建对象的过程也叫类的实例化
  • 每个对象都是类的一个具体实例(Instance),拥有类的成员变量和成员函数

假设存在某个类的定义如下:

#include 
using namespace std;

class Test
{
private:
    int m;
public:
    Test();
    Test(int m);
    void display();
    ~Test();
};

Test::Test()
{
    this->m = 0;
}

Test::Test(int m)
{
    this->m = m;
}

void Test::display()
{
    cout << "The value of m is: " << this->m << endl;
}

Test::~Test()
{
    //
}

创建对象

方式1:栈中分配内存,隐式调用构造函数

// 方式1:隐式调用构造函数;栈内存中分配空间
Test test1(1);
test1.display();

方式2:栈中分配内存,显式调用构造函数

// 方式2:显示调用构造函数;栈内存中分配空间
Test test2 = Test(1);
test2.display();

方式3:堆内存中分内存,使用new关键字显式调用构造函数;

// 方式3:new关键字;堆内存中分内存
Test* test3 = new Test(1);
test3->display();
delete test3;

方式4:其他

// 很不常用的情况:利用对象指针;但在栈中分配内存(本质和前面两种一样,不过多了一个对象指针来操作而已)
Test test4(1);
Test* test5 = &test4;
test4.display();
test5->display();

注意点:

注意1【普通对象(方式1/2)与对象指针(方式3/4)区别】

  • 方式1/2/4:使用完后不需要手动释放,该类析构函数会自动执行
  • 方式3:new申请的对象,则只有调用到delete时再会执行析构函数,如果程序退出而没有执行delete则会造成内存泄漏。【new和delete必须配合使用

注意2【普通对象(方式1/2)与对象指针(方式3/4)访问类中成员的区别】:

  • 创建对象以后,可以使用点号.来访问成员变量和成员函数,这和通过结构体变量来访问它的成员类似
  • 有了对象指针后,可以通过箭头->来访问对象的成员变量和成员函数,这和通过结构体指针来访问它的成员类似

注意3【关于方式3和方式4的说明】:

  • 在栈上创建出来的对象都有一个名字,比如 test1,test2,使用指针指向它不是必须的。
  • 但是通过 new 创建出来的对象就不一样了,它在堆上分配内存,没有名字,只能得到一个指向它的指针,所以必须使用一个指针变量来接收这个指针,否则以后再也无法找到这个对象了,更没有办法使用它。
  • 也就是说,使用 new 在堆上创建出来的对象是匿名的,没法直接使用,必须要用一个指针指向它,再借助指针来访问它的成员变量或成员函数。

注意4【只定义类指针】

这跟不用new申明对象有很大区别,类指针可以先行定义,但类指针只是个通用指针,在new之前并为该类对象分配任何内存空间。比如:

Test* ptest = NULL;

但使用普通方式创建的类对象,在创建之初就已经分配了内存空间。而类指针,如果未经过对象初始化,则不需要delete释放。

【总结】

  • 尽量使用方式1/2,不易出错;不过具体情况具体分析
  • 能使用栈就使用栈,堆涉及的问题太复杂了

new

步骤

new 实际上执行了以下三个步骤:

1、在堆中分配内存;

2、调用对应类(型)的构造函数;

3、返回相应的类型的指针 —> 所以需要用对应类型的指针变量来接收

附录(全部代码)

#include 
using namespace std;

class Test
{
private:
    int m;
public:
    Test();
    Test(int m);
    void display();
    ~Test();
};

Test::Test()
{
    this->m = 0;
}

Test::Test(int m)
{
    this->m = m;
}

void Test::display()
{
    cout << "The value of m is: " << this->m << endl;
}

Test::~Test()
{
    //
}

int main()
{
    // 方式1:隐式调用构造函数;栈内存中分配空间
    Test test1(1);
    test1.display();

    // 方式2:显示调用构造函数;栈内存中分配空间
    Test test2 = Test(1);
    test2.display();

    // 方式3:new关键字;堆内存中分内存
    Test* test3 = new Test(1);
    test3->display();
    
    // 不常用的情况:利用对象指针;但在栈中分配内存(本质和前面两种一样,不过多了一个对象指针来操作而已)
    Test test4(1);
    Test* test5 = &test4;
    test4.display();
    test5->display();

    delete test3;

    return 0;
}

你可能感兴趣的:(C++学习与知识总结,c++,开发语言)