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

ia2d9nvy  于 2023-05-08  发布在  其他
关注(0)|答案(8)|浏览(241)

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

Example example = new Example();

Example类可以有构造函数,也不能有构造函数。
我可以在C++中这样使用相同的

Example* example = new Example();

其中构造函数是强制性的。
this tutorial中我得到了我们可以像这样创建对象:

Example example;

不需要构造函数。
我有两个问题。
1.这两种创建类对象的方法有什么区别?
1.如果我正在创建一个像Example example;这样的对象,我如何在单例类中使用它?
就像我平时做的那样

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

qlvxas9a1#

我可以在c中使用同样的方法,就像这样[...],其中构造函数是强制性的。从this tutorial中我得到了我们可以创建这样的对象[...],它不需要构造函数。
这是错误的。构造函数必须存在才能创建对象。构造函数 * 可以 * 在某些条件下由编译器隐式定义,如果你不提供任何构造函数,但最终如果你想示例化一个对象,构造函数必须在那里。事实上,对象的生存期被定义为从构造函数例程返回时开始。
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)如果我正在创建对象,如Example示例;如何在单例类中使用它。
你可以这样做(简化代码):

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;

};
kmpatx3s

kmpatx3s2#

Example example;

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

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;)。

x0fgdtte

x0fgdtte3#

在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关键字,记住它将返回指针值。你应该用 * 来声明名字。如果你使用第二种方法,它不会; t删除堆中的对象。必须使用delete关键字自行删除;

delete myclass;
pengsaosao

pengsaosao4#

Example example;

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

Example* example=new Example();

这可以分为:

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

这里第一条语句创建了一个变量example,它是一个“指向Example的指针”。当构造函数被调用时,内存在堆上被分配(动态分配)。程序员的责任是在不再需要这些内存时释放它们。(C++不像Java那样有垃圾收集)。

yrdbyhpb

yrdbyhpb5#

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)Singleton C++
This SO question可以帮助您

bvn4nwqk

bvn4nwqk6#

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

Example *example = new Example();

然后你正在创建一个对象,调用构造函数并检索一个指向它的指针
如果你写

Example example;

唯一的区别是你得到的是对象,而不是指向它的指针。在这种情况下调用的构造函数与上面的相同,即默认(无参数)构造函数。
至于单例问题,你必须简单地调用你的静态方法:

Example *e = Singleton::getExample();
pprl5pva

pprl5pva7#

1)这两种创建类对象的方式有什么区别。
第一个是指向堆中构造对象的指针(new)。第二个是隐式构造的对象。(默认构造函数)
2)如果我正在创建一个类似于Example的对象;如何在单例类中使用它。
这取决于你的目标,最简单的是把它作为一个成员在类简单。
一个单例类的例子,它有一个来自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;
};
omjgkv6w

omjgkv6w8#

在第一种情况下,您使用newheap上创建对象。在第二种情况下,您正在stack上创建对象,因此当超出范围时,它将被丢弃。在C++中,当你不再需要heap上的对象时,你需要显式地使用delete删除它们。
若要从类调用静态方法,请执行

Singleton* singleton = Singleton::get_sample();

在你的主函数或其他地方。

相关问题