老革命老问题: 请问这是什么用法?是代码托管吗?

vcPlayer 2008-10-09 04:40:17
请问下面这段代码该如何解释?new 出来的子类对象指针为什么可以自动被基类得到并调用它的方法? 这是个什么技术?
class Base
{
public:
virtual void method() = 0;
static Base& instance(){return inst.get();}

static std::auto_ptr<Base> inst;
};

class Child1 : public Base
{
virtual void method(){...};
}

class Child2 : public Base
{
virtual void method(){...};
}

int WinMain(...)
{
if( /*case 1*/ )
{
new Child1();
}
else
{
new Child2();
}

Base::instance().method();

return 0;
}
...全文
200 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
Joephia 2008-10-10
  • 打赏
  • 举报
回复
....

回帖慢了
Joephia 2008-10-10
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 vcPlayer 的回复:]
嗯。akirya兄的补充就很好理解了,关键在基类的构造函数里所做的工作!这样就可以把“new Child1”解释为“Base:inst = new Child1;”的形式了。这样就是一个普通的C++用法:)! 回头再仔细看看代码。。。。
[/Quote]

如果真的是 Base:inst = new Child1;那会造成代码循环最后内存不足退出,毕竟inst是个对象引用

关于auto_ptr 个人觉得应该从下面几个方面考虑

1:智能指针,动态创建,动态释放,有效范围是函数体内,不需要手动delete

2:类似CObject的动态构造 CObject::CreateObject,并返回new 的指针或者引用(参考DECLARE_DYACREATE,DECLARE_DYANMIC)

3:引用,auto_ptr 是个类的实例,所以能用" . " 操作符,并且拥有一个指针,指向一个实例
而方法get() 则是获取指针指向对象的引用

4:用Base::Instance 只能得到最近一次动态创建的对象引用,之前的对象则被析构,释放了

5:auto_ptr 的本意是第1点,至于2,3,4 点应该需要CBase类的构造函数来实现,属于特例,不是声明一下就实现的

P.S.:
至于静态函数不能访问非静态成员的问题,我想通过Get()可以解决,在Get()中使用拷贝构造
vcPlayer 2008-10-10
  • 打赏
  • 举报
回复
惭愧,居然没看到。果如akirya 兄所言,事实确实是在基类的构造函数中予以赋值的!

唉,别人一句话把我误导到另外一个方向:(。老革命的老问题,汗。。。。。。。

谢谢各位朋友的解答,结账了:)。
yc_8301 2008-10-10
  • 打赏
  • 举报
回复
关注中。。。
akirya 兄加了一个构造函数之后,终于有了一个了解了。。疑惑也解开了。。
Base()//比如增加这样的一个构造函数
{
inst.reset( this );
}
vcPlayer 2008-10-10
  • 打赏
  • 举报
回复
嗯。akirya兄的补充就很好理解了,关键在基类的构造函数里所做的工作!这样就可以把“new Child1”解释为“Base:inst = new Child1;”的形式了。这样就是一个普通的C++用法:)! 回头再仔细看看代码。。。。
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 mycool2001 的回复:]
static std::auto_ptr <Base> inst; 是静态的,子类生成时就会自动初始化inst 指向最新的地址
使用Base::instance().method();就没有什么奇怪的了。
[/Quote]
这位仁兄能不能给出代码看看?
  • 打赏
  • 举报
回复
自己修改了一下代码这样做可以编译通过正常运行.

class Base
{
public:
Base()//比如增加这样的一个构造函数
{
inst.reset( this );
}
virtual void method() = 0;
static Base& instance(){
return *inst.get();
}

static std::auto_ptr<Base> inst;
};
std::auto_ptr<Base> Base::inst= std::auto_ptr<Base>(NULL);

class Child1 : public Base
{
virtual void method(){
printf("child1\n");
};
};

class Child2 : public Base
{
virtual void method(){
printf("child2\n");
};
};

int main()
{
if ( 1 )
{
new Child1();
}
else
{
new Child2();
}
Base::instance().method();
return 0;
}
  • 打赏
  • 举报
回复
感觉在Child2 Child1 或者Base中的构造函数中不做什么手脚的话是不能调用成功的.
cnzdgs 2008-10-09
  • 打赏
  • 举报
回复
这段代码中有很多错,需要改一下:
class Base
{
public:
virtual void method() = 0; // 纯虚函数,必须在子类中实现
static Base* instance() // 静态函数,不需要对象即可调用,但不能访问非静态成员
{
return inst.get();
}
static std::auto_ptr<Base> inst; // 静态成员变量,不需要对象即可使用
};

std::auto_ptr<Base> Base::inst; // 静态成员变量需要单独分配储存单元

class Child1 : public Base
{
virtual void method(){...};
}

class Child2 : public Base
{
virtual void method(){...};
}

int WinMain(...)
{
if( /*case 1*/ )
Base::inst.reset(new Child1());
else
Base::inst.reset(new Child2());

Base::instance()->method();
return 0;
}

在构造对象时,会建立一张虚表来储存虚函数的地址,调用虚函数时从对象的虚表来取函数地址,所以是哪个类的对象就会调用哪个类的虚函数。
wangweixing2000 2008-10-09
  • 打赏
  • 举报
回复
class Base
{
public:
virtual void method() = 0;
static Base& instance(){return inst.get();}

static int n; //这里加一句看看
static std::auto_ptr<Base> inst;
};

vcPlayer 2008-10-09
  • 打赏
  • 举报
回复
补充一下:static std::auto_ptr <Base> inst; 这个成员是基类私有的。

to mycool2001兄:

子类生成时就会自动初始化inst 指向最新的地址

是如何实现的?
yc_8301 2008-10-09
  • 打赏
  • 举报
回复
静态成员成员会在 生成实例前先初始化不假,但是为什么他会初始化为 将要生成的子类实例呢。
也是就说为什么会指向 实例化的地址呢??
按照定义应该指向Base对象才对呀?
莫非这是C++的机制???
疑惑中。。。
vcPlayer 2008-10-09
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 mycool2001 的回复:]
static std::auto_ptr <Base> inst; 是静态的,子类生成时就会自动初始化inst 指向最新的地址
使用Base::instance().method();就没有什么奇怪的了。
[/Quote]

汗,看来还是对基础知识掌握不扎实啊。谢谢这位兄弟!!
随之产生的另一个问题:静态成员可以这样来赋值吗?
mycool2001 2008-10-09
  • 打赏
  • 举报
回复
static std::auto_ptr<Base> inst; 是静态的,子类生成时就会自动初始化inst 指向最新的地址
使用Base::instance().method();就没有什么奇怪的了。

vcPlayer 2008-10-09
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 scq2099yt 的回复:]
定义基类对象指针来实现多态,这是常规的方法。
至于vcPlayer 兄的这段代码,不懂原理,只能友情帮顶了。
[/Quote]

多谢昌权兄!

5楼回复中的多态我也经常用,但这个却是有点纳闷了?还看有否熟悉的同仁出来说一下。
scq2099yt 2008-10-09
  • 打赏
  • 举报
回复
定义基类对象指针来实现多态,这是常规的方法。
至于vcPlayer 兄的这段代码,不懂原理,只能友情帮顶了。
vcPlayer 2008-10-09
  • 打赏
  • 举报
回复
难道个中玄机在“std::auto_ptr”里面?
vcPlayer 2008-10-09
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zhoujianhei 的回复:]
就是不new也可以照样能调用,只是不能访问类成员变量。
[/Quote]

为什么我new了之后,又未显式赋值给一个指针,就可以调用基类的来执行?因为根据程序运行的结果来看,它就类似于我在5楼回帖中代码的功能!我想知道是什么机制或原理把这个指针给传给基类了?
zhoujianhei 2008-10-09
  • 打赏
  • 举报
回复
就是不new也可以照样能调用,只是不能访问类成员变量。


vcPlayer 2008-10-09
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 flm007 的回复:]
用虚函数来实现多态!
[/Quote]

按常理应该是:
Base* pObj = new Child1;
pObj->method();

但上面的代码没有基类对象指针的定义,况且是直接用的基类来调用。作用是多态没错。我就想搞清楚这里面的细节!!
加载更多回复(4)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧