在 c++ 中为 object 调用的方法

Methods called for object in c++

本文关键字:方法 调用 object c++ 中为      更新时间:2023-10-16

当我们在 c++ 中创建类的对象时调用什么方法,或者当我们创建类的对象时究竟会发生什么。

如果没有其他信息,您应该假定调用类本身的一个且只有一个成员函数,即构造函数。

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* 参数"所有浇头"创建一个临时的 std::string。然后 DIYPizza::D IYPizza(std::string( 运算符可以传递这个临时 (rvalue(,然后我们从中初始化m_str,它调用 std::string(const std::string&( 复制构造函数来初始化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::D innerAtHome(( 以及它进行的四个成员函数调用。

注意:"new"不是成员函数,它是一个全局运算符。

如果答案是"五",那么要么面试官正在使用一个技巧问题,要么你错过了所问内容的一些细微差别。

好的,

我尝试矫枉过正的答案,因为没有一次已经选择了答案:当你创建一个对象时,构造函数被调用,这也涉及对成员对象的基础构造函数的调用,如果对象继承自另一个对象,你还需要调用基类的构造函数

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
    }
};

默认构造函数是为具有它的对象隐式调用的。当你用"new"创建东西时,首先分配内存,然后在该内存之上构造对象(放置new以类似的方式工作,但内存块可能由用户在其他地方显式创建(。

请注意,在某些情况下,您不知道构造函数调用的顺序:

案例1

Obj1* myobj= new Obj1 ( new Obj2, new Obj3( new Obj4) );
在这种情况下,您不知道 Obj4 是在 Obj2 之前还是之后创建的,

如果 Obj3 是在 Obj2 之前还是之后创建的,只是编译器会尝试选择"顺序"(可能因编译器和平台而异(,这也是一个非常不安全的代码:假设您在 Obj3 中收到异常,而 Obj2 已经创建,那么 Obj3 内存将永远不会被释放(在这种极端情况下,您可能会找到解决此类问题的有用工具:皮下注射/感染

(

另请参阅此答案

案例2

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

对于海湾合作委员会:

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

另请注意,"构造

函数"不像其他方法那样是一个"方法",事实上你不能将构造函数保存在 std::function 中,也不能将其与 std::bind 绑定。保存构造函数的唯一方法是使用工厂方法包装它。

嗯,这应该是你在采访中提到的5件"事情"。

假设你的类叫做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. 
    }
}

如果你正在创建一个类,意味着你正在调用该类的构造函数。如果构造函数不在代码中,则编译器将添加默认构造函数。YOu 可以重写默认构造函数以在对象创建时执行某些任务。为例:如果要创建 Person 类型的对象

Person* objPerson = new Person();

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

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

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

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