在c++; 当我们在C++中创建一个类的对象或者在创建类的对象时到底发生了什么时调用什么方法。< /p> < p>如果你正在创建一个类,意味着你正在调用那个类的构造函数。若构造函数不在代码中,编译器将添加默认构造函数。您可以重写默认构造函数以在对象创建时执行某些任务。 对于 例子: 如果要创建Person类型的对象 Person* objPerson = new Person();

在c++; 当我们在C++中创建一个类的对象或者在创建类的对象时到底发生了什么时调用什么方法。< /p> < p>如果你正在创建一个类,意味着你正在调用那个类的构造函数。若构造函数不在代码中,编译器将添加默认构造函数。您可以重写默认构造函数以在对象创建时执行某些任务。 对于 例子: 如果要创建Person类型的对象 Person* objPerson = new Person();,c++,C++,这意味着您正在调用该类的Person()方法(构造函数) class Person { public: Person() { // ... } }; 构造新对象时,将调用该类的构造函数来初始化该类的非静态成员变量(如果该类没有任何构造函数,编译器将为该类分配一个空构造函数并调用它)。构造函数可以调用其他函数(库函数或用户定义函数),但这取决于程序员在构造函数中调用的函数。此外,如果类是继承层次结构的一部分,则在实例化类的构造函数之前,编译器会调用相应的基类构造函数(

这意味着您正在调用该类的Person()方法(构造函数)

class Person {
public:
   Person() {
       // ...
    }
};

构造新对象时,将调用该类的构造函数来初始化该类的非静态成员变量(如果该类没有任何构造函数,编译器将为该类分配一个空构造函数并调用它)。构造函数可以调用其他函数(库函数或用户定义函数),但这取决于程序员在构造函数中调用的函数。此外,如果类是继承层次结构的一部分,则在实例化类的构造函数之前,编译器会调用相应的基类构造函数(请访问以获取简要说明)

实例化类的对象时:类的对象所需的内存(取决于其数据成员)在堆上分配,对该内存位置的引用由对象名存储。堆上此内存位置的单个数据成员可能会初始化,也可能不会初始化,具体取决于调用的构造函数。

好的,我尝试过多删除答案,因为没有选择过答案: 当您创建一个对象时,构造函数被调用,这还涉及到对成员对象的底层构造函数的调用,如果对象从另一个对象继承,您还需要调用基类的构造函数

class Foo: public Bar{

    std::vector<int> indices; //default constructor for indices is called

public:

    Foo(int a):Bar(a){ //you have to call constructor of Bar here
                       //else compiling error will occur
    }

};
在这种情况下,如果Obj4是在Obj2之前或之后创建的,并且如果Obj3是在Obj2之前或之后创建的,那么您没有任何线索,只是编译器会尝试选择“顺序”(这可能因编译器和平台而异),这也是一个高度不安全的代码: 假设您在Obj2已经创建时在Obj3中遇到异常,那么Obj3内存将永远不会被释放(在这种极端情况下,您可能会找到解决此类问题的有用工具:/)

案例2

静态/全局变量可能以不同的顺序初始化,您必须依赖特定的编译器函数来声明初始化顺序

对于GCC:

void f __attribute__((constructor (N)));

还要注意的是,“构造函数”不像其他函数那样是一个“方法”,实际上您不能在std::函数中保存构造函数,也不能将其与std::bind绑定。保存构造函数的唯一方法是用工厂方法包装它


正如你在采访中提到的,这应该是5个“东西”。

如果没有其他信息,你应该假设类本身只有一个成员函数被调用,构造函数

class CheesePizza {
public:
    CheesePizza() {}
};

CheesePizza barely; // will initialize by calling Foo::foo().
在许多情况下,可能会调用其他函数,例如,如果您创建一个必须创建临时对象的转换场景,例如指定std::string参数并传递const char*值

    class DIYPizza {
        std::string m_toppings;
    public:
        DIYPizza(const std::string& toppings) : m_toppings(toppings) {}
    };

    DIYPizza dinner("all of the toppings");
这必须从const char*参数“all of the toppings”创建一个临时std::string。然后可以将DIYPizza::DIYPizza(std::string)操作符传递给这个临时(右值),然后我们从它初始化m_str,它调用std::string(const std::string&)copy构造函数来初始化m_str

基本上要做的是:

// create a std::string object initialized with the c-string.
std::string rvalueString = std::string("all of the toppings");
// now we have a string to pass to DIYPizza's constructor.
DIYPizza dinner(rvalueString);
然而,此时我们仍然只调用Foo的一个成员函数。调用更多类成员的唯一方法是从调用的构造函数调用它们

class DinnerAtHome {
    void orderPizza();
    void drinkBeer();
    void watchTV(); // I was going with something more brazen, but...
public:
    DinnerAtHome() {
        orderPizza();
        drinkBeer();
        watchTV();
        drinkBeer();
        // arrival of pizza is handled elsewhere.
    }
};
现在,当您构建一个新的DinnerAtHome时,将调用5个成员函数:DinnerAtHome::DinnerAtHome(),并调用它所做的4个成员函数

注意:“new”不是成员函数,它是一个函数


如果答案是“五”,那么要么面试官使用了一个诡计性的问题,要么你错过了被问问题的一些细微差别。

假设你的班级叫CMyClass

#include "MyClass.h"

/* GLOBAL objects */
static CMyClass g_obj("foo"); // static makes this object global to this file. you can use it
                              // anywhere in this file. the object resides in the data segment 
                              // (not the heap or the stack). a string object is created prior
                              // to the constructor call.
int main(void) 
{
    ....
    if (theWorldEnds) 
    {
        /* STACK */
        CMyClass obj1; // this calls the constructor CMyClass(). It resides on the stack.
                      // this object will not exist beyond this "if" section

        CMyClass obj2("MyName"); // if you have a constructor CMyClass(string&), the compiler                 
                                // constructs an object with the string "MyName" before it calls 
                                // your constructor. so the functions called depend on which 
                                // signature of the constructor is called.

        /* HEAP */
        CMyClass *obj3 = new CMyClass(); // the object resides on the heap. the pointer obj3  
                                         // doesn't exist beyond the scope of the "if" section,  
                                         // but the object does exist! if you lose the pointer, 
                                         // you'll end up with a memory leak. "new" will call
                                         // functions to allocate memory. 

    }
}

绝对是一个构造函数。如何创建?堆栈上的变量?全局变量?静态变量?在堆上?在下面的评论中,您指出您被告知有5种方法。如果你想得到答案,你需要引用整个问题的更多内容,因为对于你问的问题,答案是“构造器”。如果答案是“5种方法”然后这个问题比你发布的问题更复杂。不,这个人只是问我,当我们创建类的对象时,会调用哪些函数。他说的是他在前面的示例中演示的特定类吗?好的,谢谢你的回答,但除了构造函数之外,还有什么其他的调用。我是在一次采访中被问到有五种方法。@LuchianGrigore Grigore先生,你是什么意思?这看起来很接近Java,但与C++
Person objPerson=new Person()相比,C++更接近不是有效的C++lol。不幸的是,我不能选择这个答案作为最佳答案。非常有创意的方法命名(永远不要低估你需要好名字的事实XD)。唯一的缺点是前两段代码中的“Foo”(当我一直使用“Foo/bar”时,我该批评谁)。向上投票:)@DarioOO Dang it-我无法抗拒:)
#include "MyClass.h"

/* GLOBAL objects */
static CMyClass g_obj("foo"); // static makes this object global to this file. you can use it
                              // anywhere in this file. the object resides in the data segment 
                              // (not the heap or the stack). a string object is created prior
                              // to the constructor call.
int main(void) 
{
    ....
    if (theWorldEnds) 
    {
        /* STACK */
        CMyClass obj1; // this calls the constructor CMyClass(). It resides on the stack.
                      // this object will not exist beyond this "if" section

        CMyClass obj2("MyName"); // if you have a constructor CMyClass(string&), the compiler                 
                                // constructs an object with the string "MyName" before it calls 
                                // your constructor. so the functions called depend on which 
                                // signature of the constructor is called.

        /* HEAP */
        CMyClass *obj3 = new CMyClass(); // the object resides on the heap. the pointer obj3  
                                         // doesn't exist beyond the scope of the "if" section,  
                                         // but the object does exist! if you lose the pointer, 
                                         // you'll end up with a memory leak. "new" will call
                                         // functions to allocate memory. 

    }
}