| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 636 人关注过本帖
标题:构造函数的问题
取消只看楼主 加入收藏
specilize
Rank: 4
等 级:业余侠客
帖 子:126
专家分:247
注 册:2011-2-20
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:5 
构造函数的问题
请看下面的代码
class Base{
public:
    Base(const std::string& logInfo)
    {}
};

class Derive:public Base{
public:
    Derive(const std::string& logInfo):Base(CreateLogInfo(logInfo))
    {}
private:
    void CreateLogInfo(const std::string& logInfo);
}

void Derive::CreateLogInfo(const std::string& logInfo)
{
    std::cout<<typeid(*this).name()<<std::endl;
}

基于上述代码有两个问题
1.构造函数的顺序是先构造基类,但是当在Derive中构造Base时,此时的this指针的类型(类型认证)不是应该表现为Base吗,那么,为什么CreateLogInfo输出为Derive呢,我的意思是
调用CreateLogInfo的当然是Derive,当是此时它应还不是Derive
2.既然Derive的构造函数未开始(指在{之前),那么在Derive的函数初始化列表中调用CreateLogInfo又怎么可以成功呢

[ 本帖最后由 specilize 于 2012-4-11 21:29 编辑 ]
搜索更多相关主题的帖子: 问题 void private public 
2012-04-11 20:55
specilize
Rank: 4
等 级:业余侠客
帖 子:126
专家分:247
注 册:2011-2-20
收藏
得分:0 
回复 2楼 rjsp
如果是这样的话,那么
class Base{
public:
    Base(const std::string& logInfo)
    {
        CreateLogInfo(logInfo);
    }
   
    virtual void CreateLogInfo(const std::string& logInfo)
    {
        std::cout<<typeid(*this).name()<<std::endl;
         .....
    }
};

class Derive:public Base{
public:
    Derive(const std::string& logInfo):Base(CreateLogInfo(logInfo))
    {

    }

    virtual void CreateLogInfo(const std::string& logInfo)
    {
        std::cout<<typeid(*this).name()<<std::endl;
        ....
    }
};
这种在基类构造函数里调用虚函数的用法就应该输出Derive了(如果构造Base时this指向本类的话),而实际上它输出Base,以至于有在多态中不要在基类里调用虚函数的条款了
如何解释这种看似很矛盾的东西呢,还是我太顽固了........
2012-04-12 13:09
specilize
Rank: 4
等 级:业余侠客
帖 子:126
专家分:247
注 册:2011-2-20
收藏
得分:0 
还是没有解决问题
2012-04-14 11:30
specilize
Rank: 4
等 级:业余侠客
帖 子:126
专家分:247
注 册:2011-2-20
收藏
得分:0 
回复 6楼 寒风中的细雨
关于调用CreateLogInfo的可以解释清楚,但是如果说this就至始至终都代表本类的话,那么如何解释下面这个东西

如果是这样的话,那么
class Base{
public:
    Base(const std::string& logInfo)
    {
        CreateLogInfo(logInfo);
    }
   
    virtual void CreateLogInfo(const std::string& logInfo)
    {
        std::cout<<typeid(*this).name()<<std::endl;
         .....
    }
};

class Derive:public Base{
public:
    Derive(const std::string& logInfo):Base(CreateLogInfo(logInfo))
    {

    }

    virtual void CreateLogInfo(const std::string& logInfo)
    {
        std::cout<<typeid(*this).name()<<std::endl;
        ....
    }
};
这种在基类构造函数里调用虚函数的用法就应该输出Derive了(如果构造Base时this指向本类的话),而实际上它输出Base,以至于有在多态中不要在基类里调用虚函数的条款了
如何解释这种看似很矛盾的东西呢,
2012-04-14 22:01
specilize
Rank: 4
等 级:业余侠客
帖 子:126
专家分:247
注 册:2011-2-20
收藏
得分:0 
回复 8楼 寒风中的细雨
版主你好,实际上我是在看EC时看到这个条款时遇到这个问题的
Item 9: Never call virtual functions during construction or destruction
它里面举了一个Transaction 的例子


class Transaction {                               // base class for all

public:                                           // transactions

  Transaction();



  virtual void logTransaction() const = 0;       // make type-dependent

                                                 // log entry

  ...

};

Transaction::Transaction()                        // implementation of

{                                                 // base class ctor

  ...

  logTransaction();                               // as final action, log this

}                                                 // transaction

class BuyTransaction: public Transaction {        // derived class

public:

  virtual void logTransaction() const;          // how to log trans-

                                                // actions of this type

  ...

};

class SellTransaction: public Transaction {      // derived class

public:

 virtual void logTransaction() const;           // how to log trans-

                                                // actions of this type

  ...

};




Consider what happens when this code is executed:


BuyTransaction b;

并且在后边他解释到

During base class construction of a derived class object, the type of the object is that of the base class. Not only do virtual functions resolve to the base class, but the parts of the language using runtime type information (e.g., dynamic_cast (see Item 27) and typeid) treat the object as a base class type. In our example, while the transaction constructor is running to initialize the base class part of a BuyTransaction object, the object is of type TRansaction. That's how every part of C++ will treat it, and the treatment makes sense: the BuyTransaction-specific parts of the object haven't been initialized yet, so it's safest to treat them as if they didn't exist. An object doesn't become a derived class object until execution of a derived class constructor begins.

所以才有了我在里面写下typeid的代码,并且我测试过,确实没问题,输出的确实是class Transaction ,所以才有了我提出的既然在构造时表现出来的是Transaction ,那么怎么还可以调用继承类的成员函数的疑问,实际上在没看这个之前倒是没有考虑这么多的
2012-04-14 23:30
specilize
Rank: 4
等 级:业余侠客
帖 子:126
专家分:247
注 册:2011-2-20
收藏
得分:0 
回复 12楼 寒风中的细雨
嗯,好像真的是我越想越复杂,以至于弄混了
2012-04-15 09:14
快速回复:构造函数的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.012967 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved