| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 636 人关注过本帖
标题:构造函数的问题
只看楼主 加入收藏
specilize
Rank: 4
等 级:业余侠客
帖 子:126
专家分:247
注 册:2011-2-20
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:12 
构造函数的问题
请看下面的代码
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
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:10 
你说得对,但this就代表本类(编译时就确定了),即便其指向的对象还没有构建完毕,所以“此时的this指针的类……”是错误的
2012-04-12 08:19
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
寒风中的细雨
Rank: 17Rank: 17Rank: 17Rank: 17Rank: 17
等 级:贵宾
威 望:66
帖 子:1710
专家分:8645
注 册:2009-9-15
收藏
得分:10 
回复 楼主 specilize
上面说的两点 都有问题

首先this,实例化(对象)开始的时候就已经有了  是和对象放在一起说的。  类定义好了 成员函数都是公共的  谁的可以调用  就算是定义一个指向该类类型的指针,让指针指向NULL 还是可以调用的到,只是在访问数据成员的时候会报错,因为没分配空间(存放数据成员的)。

这么一来第二个就不是什么问题了, 因为它确实是可以调用的   可以加个this->试试
2012-04-12 19:25
specilize
Rank: 4
等 级:业余侠客
帖 子:126
专家分:247
注 册:2011-2-20
收藏
得分:0 
还是没有解决问题
2012-04-14 11:30
寒风中的细雨
Rank: 17Rank: 17Rank: 17Rank: 17Rank: 17
等 级:贵宾
威 望:66
帖 子:1710
专家分:8645
注 册:2009-9-15
收藏
得分:0 
还是上面的不清楚?
2012-04-14 11:32
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
寒风中的细雨
Rank: 17Rank: 17Rank: 17Rank: 17Rank: 17
等 级:贵宾
威 望:66
帖 子:1710
专家分:8645
注 册:2009-9-15
收藏
得分:0 
这是构造    按照你这个理论    我有虚函数的时候   你的基类还不用构造

构造的时候 总是先构造父类先,


运行时  的识别 (动态)    用在这儿用的时机就不对

首现不知道你有没有运行你上面的程序  typeid这样调用在运行时会出错   


2012-04-14 22:40
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
寒风中的细雨
Rank: 17Rank: 17Rank: 17Rank: 17Rank: 17
等 级:贵宾
威 望:66
帖 子:1710
专家分:8645
注 册:2009-9-15
收藏
得分:0 
程序代码:
#include <typeinfo>
#include <iostream>
#include <string>

class Base
{
public:
    Base(const std::string &logInfo)
    {
        CreateLogInfo(logInfo);
    }
    virtual std::string CreateLogInfo(const std::string &logInfo)
    {
        std::cout << typeid(*this).name() << std::endl;
        return logInfo;
    }
};

class Derive:public Base
{
public:
    Derive (const std::string& logInfo):Base(CreateLogInfo(logInfo))
    {
    }
    virtual std::string CreateLogInfo(const std::string logInfo)
    {
        std::cout << typeid(*this).name() << std::endl;
        return logInfo;
    }
};

int main()
{
    Derive obj("obj");
    return 0;
}

/*
[color=#0000FF]#include <typeinfo>
#include <iostream>
#include <string>

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
{
    Derive (const std::string& logInfo):Base(CreateLogInfo(logInfo))
    {
    }
    virtual void CreateLogInfo(const std::string logInfo)
    {
        std::cout << typeid(*this).name() << std::endl;
    }
};

int main()
{
    Derive obj;
    return 0;
}
[/color]*/
2012-04-15 00:11
快速回复:构造函数的问题
数据加载中...
 
   



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

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