关于MFC中一个内嵌类的实现

frankzch 2006-12-15 11:58:16
在一个MFC项目中,有2个类需要设计为内嵌类。简化如下
//Outer.h
class Outer
{
class Inner: public CDialog
{
DECLARE_DYNAMIC(Inner)
........
}
......
}

//Outer.cpp
IMPLEMENT_DYNAMIC(Inner, CDialog)
........


问题来了,,这样不能通过编译,说无法识别类Inner。
内部类一般可以通过标识符Outer::Inner来访问,,但是这样写IMPLEMENT_DYNAMIC(Outer::Inner, CDialog)同样出问题,因为宏是简单字符代换。
各位大虾怎么解决这个问题,谢谢了(先假定必须使用内嵌类)
...全文
348 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
zcp126 2006-12-15
  • 打赏
  • 举报
回复
IMPLEMENT_DYNAMIC(Inner, CDialog)是要展开的,而内嵌的外面估计是找不到的,就错了。
恐怕不成了。
wshcdr 2006-12-15
  • 打赏
  • 举报
回复
用宏估计是有问题

frankzch 2006-12-15
  • 打赏
  • 举报
回复
楼上2位:
include有的

另外设计成内嵌类是为了让类层次结构更清晰,如果不用内嵌类则有很多方法可以实现。现在的问题就是如何在使用内嵌类的情况下解决这个问题
一分之千 2006-12-15
  • 打赏
  • 举报
回复
class Inner: public CDialog单独作为一个类,使用友元?
zcp126 2006-12-15
  • 打赏
  • 举报
回复
没碰到过。试着
//Outer.cpp
class Inner
IMPLEMENT_DYNAMIC(Inner, CDialog)
看看,另外#include有吧
eplanet 2006-12-15
  • 打赏
  • 举报
回复
学习
hhlily 2006-12-15
  • 打赏
  • 举报
回复
up
frankzch 2006-12-15
  • 打赏
  • 举报
回复
如能回答立即给分,在线等
yf956613 2006-12-15
  • 打赏
  • 举报
回复
我的怎么写也通过不了
IMPLEMENT_DYNAMIC(Outer, CDialog)

typedef Inner::Outer Outer;//后面的名字一定要跟前面一样
IMPLEMENT_DYNAMIC(Inner, CDialog)

都写了,不行
各位大虾 怎么写呀?
frankzch 2006-12-15
  • 打赏
  • 举报
回复
找到正确方法了,就是
Typedef Outer::Inner Inner;//后面的名字一定要跟前面一样
IMPLEMENT(Inner, CDialog)

感谢我的师兄告诉我这个解决办法。也多谢楼上各位
0011411 2006-12-15
  • 打赏
  • 举报
回复
如果一个类在另外一个类或者接口内被声明,就被称作内嵌类nested class。 同样如果一个接口在另外一个

类或者接口类中被声明,就被称作内嵌接口nested interface。而最高层的类或者最高层的接口类都不能叫做内嵌类。

内嵌类分成四种内嵌类和一种内嵌接口,正式的描述如下:

static member classes and interfaces. 静态类和接口类

non-static member classes 非静态类

local classes 本地类

anonymous classes 匿名类

一个静态类或者接口在类的内部仍旧被定义成一个作为静态的类或者接口。这样的一个内嵌类可以被实例化就

好像一个的最高层类。其中接口类总是被定义不是最高层类或者静态类。

非静态成员类被定义成如果类的实例成员,就类似于类中定义的域和实例方法。

本地类可以被定义在一个上下文块中,如一个方法体内或者一个本地的上下文块中。这有点类似域本地的变量

被定义在方法体中或者本地上下文块中。

匿名类可以被定义成用一种比较随意的方式来进行表达或者实例化。

注意:内嵌类或者接口在他们所在的类中命名不能相同。

class TLC {
static class SMC {} 静态内嵌类
interface SMI {} 静态内嵌接口
class NSMC {} 非静态类(内部类)
void nsm() {
class NSLC {} 本地内部类,在非静态上下文中。
}
static void sm() {
class SLC {} 本地内部类在静态上下文中。
}
SMC nsf = new SMC() {}; 匿名内部类,在非静态上下文中。

static SMI sf = new SMI() {}; 匿名内部类,在静态上下文中。

}

一些基本的原则,

1. 最高层类或者最高层接口必须被定义在Package的层次下,并且这些类的修饰器必须是Public或者是默认的

。而内嵌的静态类或者内嵌的接口则必须被定义在修饰器为静态的类或者接口中。

2. 不管是静态类是不需要通过实例来实例化一个对象的,比如
如果静态内嵌类 StaticTemp
ToplevelClass.StaticTemp NewObject = new ToplevelClass.StaticTemp();

但是换成非静态类 NonStaticTemp的话,我们实例化对象就不能这样了,应该:
ToplevelClass topRef = new ToplevelClass();
ToplevelClass.NonStaticTemp NewObject1 = topRef.new ToplevelClass.NonStaticTemp();

或者如此书写也是正确的
ToplevelClass.NonStaticMemberClass NewObject2 = new ToplevelClass().new NonStaticMemberClass

();

3. 静态的内嵌类可以访问所有的类范围内的静态变量,但不能访问非静态变量。而非静态出了可以访问静态

变量之外,还能访问非静态变量。这点是要特别注意的。

4. 静态内嵌类和非静态内嵌类的另一个区别在于:
A.静态类内中可以定义声明任何的(包括再定义静态的类或者非静态的类)类。
B.非静态类内中只可以定义非静态类,以及修饰器为final的静态变量(field)。(注意修饰为final的类不

能定义。因为这里的原则是static的类只能定义在topLevelClass下或者静态类下。)

5. 本地类是一种比较特殊的内嵌类使用情况。
A.首先本地类定义时,不能在类前放置任何的修饰符,其概念就是本地内嵌类前不能方式

public,protected或者是private修饰字符。

B.本地内嵌类中的实例化过程可以参照2中所描述的内容。

C.本地内嵌类中非静态的内嵌类能访问上下文中的所有变量,以及本地的声明为final的变量。注意非

final的变量是不能被访问的。在静态本地内嵌类可以访问上下文中所有的静态对象,以及定义为final的本地

对象。

D.本地内嵌类中只能访问类中非静态声明的对象以及定义为fianl的静态对象。

6. 匿名类的使用情况。见5,和本地内嵌类的使用方式雷同。

frankzch 2006-12-15
  • 打赏
  • 举报
回复
这是一个实际项目,Inner实现部分会非常大,如果都放到头文件里会很不好看的。


现在我没有其他办法了,,只好把这个IMPLEMENT_DYNAMIC和DECLARE_DYNAMIC全部去掉算了,应该不会有太大影响
yjgx007 2006-12-15
  • 打赏
  • 举报
回复
自已写一个IMPLEMENT_DYNAMIC
goodboyws 2006-12-15
  • 打赏
  • 举报
回复
IMPLEMENT_DYNAMIC(Inner, CDialog)放到头文件去,也就是说把Inner的部分实现放到Outer里
frankzch 2006-12-15
  • 打赏
  • 举报
回复
VC7吧,我用的是VS 2003

用typedef我也试过了,还是不能编译通过.
typedef Outer::Inner InnerA;
出错“e:\ZCH\NewMember2\NewMember2\NewMember\Outer.cpp(114): error C2039: “classInnerA” : 不是“Outer::Inner”的成员
frankzch 2006-12-15
  • 打赏
  • 举报
回复
DECLARE_DYNAMIC(Outer::Inner) 不行的,宏是字符代换,Outer后面的::在宏代换里就是普通字符,不会把它理解为作用域的。

IMPLEMENT_DYNAMIC(Inner, CDialog)放到头文件去也不行,编译不能通过。
  • 打赏
  • 举报
回复
但是这样写IMPLEMENT_DYNAMIC(Outer::Inner, CDialog)同样出问题,因为宏是简单字符代换。

这个问题可以用typedef 试试看
  • 打赏
  • 举报
回复
那个版本的vc?
vc6是不支持内嵌类的
goodboyws 2006-12-15
  • 打赏
  • 举报
回复
IMPLEMENT_DYNAMIC(Inner, CDialog)放到头文件去
yjgx007 2006-12-15
  • 打赏
  • 举报
回复
试下DECLARE_DYNAMIC(Outer::Inner)
加载更多回复(1)

16,472

社区成员

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

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

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