如何在C++中创建类对象

How do I create a class object in C++?

本文关键字:创建 对象 C++      更新时间:2023-10-16

我有Java背景。在Java中,我们创建这样的类对象。

Example example = new Example();

示例类可以有构造函数,也可以不能有构造函数。

我可以像这样在C++中使用相同的

Example* example = new Example();

构造函数是强制性的。

从本教程中,我了解到我们可以创建这样的对象:

Example example;

不需要构造函数。

我有两个问题。

  1. 创建类对象的两种方法之间有什么区别?

  2. 如果我正在创建一个像Example example;这样的对象,如何在单例类中使用它?

就像我通常这样做一样。

Sample* Singleton::get_sample() {
    if (sample == NULL) {
        sample = new Sample();
    }
    return sample;
}

我可以像这样在 c++ 中使用相同的 [...]构造函数是强制性的。从本教程中,我了解到我们可以创建这样的对象 [...]不需要构造函数。

这是错误的。构造函数必须存在才能创建对象。如果您不提供任何构造函数,则在某些情况下,编译器可以隐式定义构造函数,但如果您希望实例化对象,则最终构造函数必须存在。实际上,对象的生存期被定义为在构造函数例程返回时开始。

从C++11标准第3.8/1段:

[...]T 类型的对象的生存期在以下情况下开始:

— 获得具有 T 型正确对齐和大小的存储,以及

— 如果对象具有非平凡的初始化,则其初始化完成。

因此,构造函数必须存在。

1(创建类对象的方式有什么区别。

当您使用自动存储持续时间实例化对象时,如下所示(其中X是某个类(:

X x;

您正在创建一个对象,当它超出范围时将自动销毁。另一方面,当您执行以下操作时:

X* x = new X();

您正在动态创建一个对象,并将其地址绑定到指针。这样,当您的x指针超出范围时,您创建的对象不会被销毁。

在现代C++中,这被认为是一种可疑的编程实践:尽管指针很重要,因为它们允许实现引用语义,但原始指针是不好的,因为它们可能导致内存泄漏(对象超过其所有指针并且永远不会被破坏(或悬空指针(指针超过它们指向的对象,在取消引用时可能导致未定义行为(。

实际上,在使用new创建对象时,您始终必须记住使用delete销毁它:

delete x;

如果您需要引用语义并被迫使用指针,则在 C++11 中,您应该考虑改用智能指针

std::shared_ptr<X> x = std::make_shared<X>();

智能指针可以解决内存管理问题,这就是原始指针让您头疼的原因。事实上,智能指针与 Java 或 C# 对象引用几乎相同。"几乎"是必要的,因为程序员必须注意不要通过拥有智能指针来引入循环依赖关系。

2(如果我正在创建类似示例示例的对象;如何在单例类中使用它。

你可以做这样的事情(简化代码(:

struct Example
{
    static Example& instance()
    {
        static Example example;
        return example;
    }
 private:
    Example() { }
    Example(Example const&) = delete;
    Example(Example&&) = delete;
    Example& operator = (Example const&) = delete;
    Example& operator = (Example&&) = delete;
};
Example example;

这是类型为 Example 的名为 example 的变量的声明。这将默认初始化涉及调用其默认构造函数的对象。该对象将具有自动存储持续时间,这意味着当它超出范围时,它将被销毁。

Example* example;

这是一个名为 example 的变量的声明,它是指向Example指针。在这种情况下,默认初始化使其未初始化 - 指针没有特别指向任何地方。这里没有Example对象。指针对象具有自动存储持续时间。

Example* example = new Example();

这是一个名为 example 的变量的声明,该变量是指向Example指针。如上所述,此指针对象具有自动存储持续时间。然后用 new Example(); 的结果对其进行初始化。此new表达式创建一个具有动态存储持续时间的Example对象,然后返回指向该对象的指针。因此,example指针现在指向该动态分配的对象。Example对象是值初始化的,如果有,它将调用用户提供的构造函数,或者将所有成员初始化为 0。

Example* example = new Example;

这与上一行类似。不同之处在于Example对象是默认初始化的,它将调用 Example 的默认构造函数(如果它不是类类型,则保持未初始化(。

动态分配的对象必须delete d(可能带有 delete example; (。

有两种方法可以在 c++ 中制作/创建对象。

第一个是:

MyClass myclass; // if you don;t need to call rather than default constructor    
MyClass myclass(12); // if you need to call constructor with parameters

第二个是:

MyClass *myclass = new MyClass();// if you don;t need to call rather than default constructor
MyClass *myclass = new MyClass(12);// if you need to call constructor with parameters

在 c++ 中,如果使用 new 关键字,对象将存储在堆中。 如果您长时间使用此对象,并且如果您使用第一种方法,它将存储在堆栈中,这将非常有用。 它只能在短时间内使用。注意:如果使用 new 关键字,请记住它将返回指针值。您应该使用 * 声明名称。如果使用第二种方法,它不会删除堆中的对象。您必须使用删除关键字自行删除;

delete myclass;
Example example;

这里的例子是堆栈上的一个对象。

Example* example=new Example();

这可以分为:

Example* example;
....
example=new Example();

在这里,第一条语句创建一个变量示例,该示例是"指向示例的指针"。调用构造函数时,将在堆上为其分配内存(动态分配(。程序员有责任在不再需要此内存时释放此内存。(C++没有像Java那样的垃圾回收(。

1(创建类对象的方式有什么区别。

a( 指针

Example* example=new Example();
// you get a pointer, and when you finish it use, you have to delete it:
delete example;

b( 简单申报

Example example;

你得到一个变量,而不是一个指针,它将被销毁到声明的范围之外。

2( 单例C++

这个SO问题可能会对您有所帮助

首先,这两种情况都调用构造函数。如果你写

Example *example = new Example();

然后创建一个对象,调用构造函数并检索指向它的指针

如果你写

Example example;

唯一的区别是获取的是对象,而不是指向它的指针。在这种情况下调用的构造函数与上述相同,默认(无参数(构造函数。

至于单例问题,您必须通过编写以下内容来简单地调用静态方法:

Example *e = Singleton::getExample();

1(两者创建类的方式有什么区别 对象。

第一个是指向堆中构造对象的指针(按 new (。第二个是隐式构造的对象。(默认构造函数(

2(如果我正在创建类似示例示例的对象;如何在 单例类。

这取决于你的目标,最简单的就是简单地把它作为班级的一员。

具有来自Example类的对象的单例类的示例:

class Sample
{
    Example example;
public:
    static inline Sample *getInstance()
    {
        if (!uniqeInstance)
        {
            uniqeInstance = new Sample;
        }
        return uniqeInstance;
    }
private:
    Sample();
    virtual ~Sample();
    Sample(const Sample&);
    Sample &operator=(const Sample &);
    static Sample *uniqeInstance;
};
在第

一种情况下,您使用 newheap上创建对象。在第二种情况下,您将在stack上创建对象,因此当超出范围时,它将被释放。在C++中,当您不再需要对象时,您需要使用 delete 显式删除heap上的对象。

若要从类调用静态方法,请执行

Singleton* singleton = Singleton::get_sample();

在您的主要功能或任何地方。