在c ++中调用object的方法

时间:2013-09-30 05:24:18

标签: c++

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

6 个答案:

答案 0 :(得分:3)

如果没有附加信息,您应该假设调用类本身中只有一个成员函数,即构造函数。

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

CheesePizza barely; // will initialize by calling Foo::foo().

在许多情况下,可能会调用其他函数,例如,如果您创建必须创建临时对象的转换方案,例如指定std :: string参数并传递const char * value。

    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,“所有的toppings”。然后DIYPizza :: DIYPizza(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 :: DinnerAtHome()和它所做的四个成员函数调用。

注意:“new”不是成员函数,而是global operator

如果答案是“五”,那么面试官正在使用一个技巧问题,或者你错过了一些细微的问题。

答案 1 :(得分:1)

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

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”创建内容时,会分配第一个内存,然后在该内存之上构建对象(placement new以类似的方式工作,但内存块可能由用户在其他地方明确创建)。

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

案例1

Obj1* myobj= new Obj1 ( new Obj2, new Obj3( new Obj4) );

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

see also this answer

案例2

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

海湾合作委员会

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

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

如你在采访中提到的那样,这应该是5个“事物”。

答案 2 :(得分:0)

如果要创建类,则意味着您正在调用该类的构造函数。如果构造函数不在您的代码中,那么编译器将添加默认构造函数。你可以覆盖默认构造函数来执行对象创建的一些任务。 对于 例: 如果要创建Person类型的对象

Person* objPerson = new Person();

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

让我们假设您的类名为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. 

    }
}