这样设计class可不可以?

时间:2023-01-27 08:36:05
有个基类:A,
现有2个子类X,Y都从A派生,请问X中再包含Y可不可以?有什么优缺点?

class A { }
class X : public A;
class Y : publc A;

class X
{
private: Y y;
...
}

37 个解决方案

#1


当然可以,它们是包含关系,没有冲突,但觉得内容已经重叠

#2


从语法上说可以。
但是真要这么做,最好用指针,而且是基类指针。

#3


为什么非要那么做?



class A { } 
class X ; 
class Y ; 

class X: public A {...}

#4


语法上是没有问题的,但这样使用的话,X中等于有了两个A的拷贝。
造成重复。

#5


语法上没有错,并不代表设计上没问题

编程中语法是次要的,只要编译通过就行,设计才是最重要的

设计越好,越容易实现,写代码越容易且不易出错

#6


多谢大家。我也是这么考虑的。
原因是我想把最基础的类设计成一个窗口物体,包含最基本的句柄,id,和座标,都是protected。
然后这样其他所有的类都是继承而来,但有的物体(城市),我想也让它包含其他物体(到其他城市的路径),
这些路径也都是一个个小的物体,我想让他们属于各自的城市,这样搜索起来方便。
这样就有问题了:

如果把这个路径设计成一个新类,它又要重新写最基本的句柄,id,和座标,也不是很爽。大家有什么建议?

#7


需要三个类吗?

class x{
};

class y: public x{
private:
    y *abut;//邻接的城市,用链表实现,在构造函数中初始化为NULL,写专门的函数增加城市.
};

#8


把它们以树的形式组织起来

#9


感觉没什么意思 怎么写 不提倡啊

#10


不提倡,其中一个子类多了一份冗余数据

#11


引用 7 楼 PcrazyC 的回复:
需要三个类吗?
C/C++ codeclassx{
};classy:publicx{private:
    y*abut;//邻接的城市,用链表实现,在构造函数中初始化为NULL,写专门的函数增加城市.};


城市必须作为窗口显示出来,路径中的各个点也必须作为窗口显示。

#12


按照6楼的观点,这样设计没有问题。

#13


引用 11 楼 damo_xu 的回复:
引用 7 楼 PcrazyC 的回复:
城市必须作为窗口显示出来,路径中的各个点也必须作为窗口显示。


class x{
};

class y: public x{
private:
    y *abut;//邻接的城市,用链表实现,在构造函数中初始化为NULL,写专门的函数增加城市.
};


X是窗口,Y在X上派生不就可以用窗口显示了吗?而邻接的城市是指针类型,你添加的时候NEW出来不也是窗口吗?

#14


理论上是可以的,但是就是有点不太符合大家的习惯而已

#15


up

#16


城市是个窗口,呵呵有意思。

#17


引用 13 楼 PcrazyC 的回复:
X是窗口,Y在X上派生不就可以用窗口显示了吗?而邻接的城市是指针类型,你添加的时候NEW出来不也是窗口吗?


可能老兄没有理解我的问题: 我的邻接的城市其实就是这么实现的。
关键是路径,一个个路径点是包含在城市里的一个非类成员呢?还是作为一个
单独的class呢(因为也是窗口,就打算继承A类)?


我这两天找了几本书来看,看到The C++ Programming Language Bjarne_Stroustrup上有句话:
"不要从具体的类继承。" 经典!!!而且正好那我这样的反例来说明会产生一个逻辑的回圈,导致各个类关系混乱。

所以我打算改成:不用继承。最小的通用窗口是个具体的类(就是上面的A),其他的城市包含这个类。

#18


按lz的需求,这么设计没什么问题

就像CDialog和CEdit等控件类都是继承自CWnd,我也经常在CDialog里面有CEdit成员,有时也用指针,看你个人爱好了,用成员的时候实例化时自动会分配空间,用指针则自行分配空间实例化。

不过如果按lz的设计这些实例如果都是独立的话,最好用指针;如果非独立的,比如某个城市内“绑定”有某些路径的话,则直接用类对象成员即可,安全且方便。

#19


嗯,比原来的好。。。
但不能骄傲喔,想想有没有更好的^_^

引用 17 楼 damo_xu 的回复:
引用 13 楼 PcrazyC 的回复:
X是窗口,Y在X上派生不就可以用窗口显示了吗?而邻接的城市是指针类型,你添加的时候NEW出来不也是窗口吗? 
 

可能老兄没有理解我的问题: 我的邻接的城市其实就是这么实现的。 
关键是路径,一个个路径点是包含在城市里的一个非类成员呢?还是作为一个 
单独的class呢(因为也是窗口,就打算继承A类)? 


我这两天找了几本书来看,看到The C++ Programming Language Bjarne_Stroustrup上有…

#20


引用 19 楼 ysuliu 的回复:
嗯,比原来的好。。。
但不能骄傲喔,想想有没有更好的^_^

哈哈哈哈哈哈,新年快乐。

引用 18 楼 wiowei 的回复:
按lz的需求,这么设计没什么问题
就像CDialog和CEdit等控件类都是继承自CWnd,我也经常在CDialog里面有CEdit成员,有时也用指针,看你个人爱好了,用成员的时候实例化时自动会分配空间,用指针则自行分配空间实例化。
不过如果按lz的设计这些实例如果都是独立的话,最好用指针;如果非独立的,比如某个城市内“绑定”有某些路径的话,则直接用类对象成员即可,安全且方便。

我其实一直也在想这个问题,肯定还要某些设计类的知识。唉,突然发现:陪伴了我4年的C/C++,我对它其实一无所知。

#21


可以

#22


引用 18 楼 wiowei 的回复:
不过如果按lz的设计这些实例如果都是独立的话,最好用指针;如果非独立的,比如某个城市内“绑定”有某些路径的话,则直接用类对象成员即可,安全且方便。


老兄一眼就看出我想绑定路径,牛!
不过如开始所说,基类就是简单的hwnd,id,都是protected,城市和路径都是继承而来,城市中如果包含路径实例,这样城市的class中的hwnd,id栏位会和路径的hwnd,id栏位重复吧?会不会有些乱?

#23


最好别这样

#24


引用 22 楼 damo_xu 的回复:
引用 18 楼 wiowei 的回复:
不过如果按lz的设计这些实例如果都是独立的话,最好用指针;如果非独立的,比如某个城市内“绑定”有某些路径的话,则直接用类对象成员即可,安全且方便。 
 

老兄一眼就看出我想绑定路径,牛! 
不过如开始所说,基类就是简单的hwnd,id,都是protected,城市和路径都是继承而来,城市中如果包含路径实例,这样城市的class中的hwnd,id栏位会和路径的hwnd,id栏位重复吧?会不会有些乱?

每个类是一个命名域,不同域内的变量名重复没关系,当然你自己要分清楚,比如ID:
class A {
public:
A(int id):ID(id){};
int getID(){return ID;}
protected:
int ID;
};
class Y: public A
{
public:
Y(int id):A(id){}
};

class X: public A
{
private:
Y y;
public:
X(int id,int id_y):A(id),y(id_y){}
int getYID(){return y.getID();}
};
X对象只能用getID来获取自己的ID,而用getYID()来获取成员y的ID

#25



看看设计模式吧
能写一个类不是问题
能写出很多类,而且要把类写好,结合好,还是要看看设计模式的
你的x,y类都是从a继承,同时x里面有组合了y,问题倒是没有问题,类的耦合和类的重叠就让整个类的设计显得很不好了

#26


为了避免相互包含等副作用,最好用指针



class obj 
{

};

class path : public obj
{

};

class city : public obj
{
public :
    vector<path*> vPaths;
};

#27


引用 26 楼 Chiyer 的回复:
为了避免相互包含等副作用,最好用指针
 我也就是想这么写,吼吼。不过好像指针的副作用更大。
引用 24 楼 wiowei 的回复:
每个类是一个命名域,不同域内的变量名重复没关系,当然你自己要分清楚,比如ID:...
 变量名不是问题。
class A {
protected: ID;
...};
关键就是这个ID栏位。X里面有,Y里面也有。
所以让X里面包含Y,总感觉在X里面重复冗余定义了一个ID栏位,总感不爽,
就如同前面几位仁兄和ztz0223回复的那样:
引用 25 楼 ztz0223 的回复:
你的x,y类都是从a继承,同时x里面有组合了y,问题倒是没有问题,类的耦合和类的重叠就让整个类的设计显得很不好了
 

除非把继承看做是为了定义一个新类而避免敲相同的代码:
就是除非上面的代码完全等同于:
-没有 class A
-class Y { private: ID; ...};
-class X { private: ID; Y y; ...};

#28


引用 27 楼 damo_xu 的回复:
关键就是这个ID栏位。X里面有,Y里面也有。 
所以让X里面包含Y,总感觉在X里面重复冗余定义了一个ID栏位,总感不爽, 

这个ID是其成员的ID,何为重复呢?每个对象的ID只有一个,这种设计方法每个X对象总有着自己“独占”的Y对象,何况你的Y是private,也就是说不可能会重复。
我觉得这种思路下的设计就算是用指针也要在X实例化时在构造函数里分配空间实例化成员,还不如直接用类对象做成员更加方便且安全。除非你的Y并不是“绑定”的,比如不是private;不是在X实例化时就固定下来的(需要动态生成);生命周期不是伴随着X对象。

#29


引用 28 楼 wiowei 的回复:
这个ID是其成员的ID,何为重复呢?


那继承就是为了定义一个新类而避免敲相同的代码了吗?:
上面继承A的代码完全等同于:
-没有 class A
-class Y { private: ID; ...};
-class X { private: ID; Y y; ...};

#30



-class A { protected: int ID; };
-class X : public A {};
-class Y { protected: A a; };

如果构造两个class , X和Y有什么不同?好像一样吧?

#31


哦,不一样。
-class A { protected: int ID; };
-class X : public A {}; 
但可以说X就是A吗?就是定义了两个完全相同的类,只是名称不同。

#32


继承是为了“特例化”呀,你的X和Y总会有些跟别人不同的东西吧,拿你的例子来说:
城市X总有城市名、邮编、所处省、人口数等等
街道Y总会有街道名、长度、方位、区域等

基类是为了提取出“共同”的东西,继承类是为了体现“特殊”的东西,你要是X和Y都一样何必要两个类。。跟A一样何必要继承。。

#33


多谢了。
我举这个特殊的例子其实还是理解我原来那个疑问,子类中包含另一个子类,我也像前面几位回答我的网友一样的认为不妥。
原因是:
Y继承A,有了“共同”的东西;(可以表示为:Y是一个大框,套在里面的是小框A)
X继承A,有了“共同”的东西;(可以表示为:X是一个大框,套在里面的是小框A)
然后X再包含Y,怎么表示这个X类呢?(不是说一个object的实现,而只是问怎么表示这个class?)

(应该表示为:大框X里面有一个“共同”部份和一个次大框Y,Y里面还有一个“共同”部份。)

这也就是我们所说的X里面有两个“共同”部份。

#34


引用 33 楼 damo_xu 的回复:
多谢了。 
我举这个特殊的例子其实还是理解我原来那个疑问,子类中包含另一个子类,我也像前面几位回答我的网友一样的认为不妥。 
原因是: 
Y继承A,有了“共同”的东西;(可以表示为:Y是一个大框,套在里面的是小框A) 
X继承A,有了“共同”的东西;(可以表示为:X是一个大框,套在里面的是小框A) 
然后X再包含Y,怎么表示这个X类呢?(不是说一个object的实现,而只是问怎么表示这个class?) 

(应该表示为:大…


这个"共同"的东西只是从数据的角度来说的,具体到继承类可就不是“共同”的了,会被“特殊”化的(内容)

就拿你所说的hwnd和iD来说,X有,Y有,X包含Y,则X中有“双份”,但这双份是“重复”的么?X需要,Y需要,可以单份么?

关键是你包含了Y,到底Y是不是不需要“这份”?如果需要,何来重复?

#35


不止要考虑编译,重在设计

#36


引用 34 楼 wiowei 的回复:
这个"共同"的东西只是从数据的角度来说的,具体到继承类可就不是“共同”的了,会被“特殊”化的(内容)
就拿你所说的hwnd和iD来说,X有,Y有,X包含Y,则X中有“双份”,但这双份是“重复”的么?X需要,Y需要,可以单份么?
关键是你包含了Y,到底Y是不是不需要“这份”?如果需要,何来重复?


吼吼,早上醒来,我也突然想通了这个道理!真是的,何来重复?! 
看来结论可以下了:如果需要,子类可以包含另一个子类。

多谢老兄不厌其烦,送200分,表个心意,以后还应会请教。

并多谢大家了。新年快乐。

#37


晕,每帖只能加分一次,此帖已加过分,不能再加了。
吼吼,wiowei兄,俺欠你一百分。

#1


当然可以,它们是包含关系,没有冲突,但觉得内容已经重叠

#2


从语法上说可以。
但是真要这么做,最好用指针,而且是基类指针。

#3


为什么非要那么做?



class A { } 
class X ; 
class Y ; 

class X: public A {...}

#4


语法上是没有问题的,但这样使用的话,X中等于有了两个A的拷贝。
造成重复。

#5


语法上没有错,并不代表设计上没问题

编程中语法是次要的,只要编译通过就行,设计才是最重要的

设计越好,越容易实现,写代码越容易且不易出错

#6


多谢大家。我也是这么考虑的。
原因是我想把最基础的类设计成一个窗口物体,包含最基本的句柄,id,和座标,都是protected。
然后这样其他所有的类都是继承而来,但有的物体(城市),我想也让它包含其他物体(到其他城市的路径),
这些路径也都是一个个小的物体,我想让他们属于各自的城市,这样搜索起来方便。
这样就有问题了:

如果把这个路径设计成一个新类,它又要重新写最基本的句柄,id,和座标,也不是很爽。大家有什么建议?

#7


需要三个类吗?

class x{
};

class y: public x{
private:
    y *abut;//邻接的城市,用链表实现,在构造函数中初始化为NULL,写专门的函数增加城市.
};

#8


把它们以树的形式组织起来

#9


感觉没什么意思 怎么写 不提倡啊

#10


不提倡,其中一个子类多了一份冗余数据

#11


引用 7 楼 PcrazyC 的回复:
需要三个类吗?
C/C++ codeclassx{
};classy:publicx{private:
    y*abut;//邻接的城市,用链表实现,在构造函数中初始化为NULL,写专门的函数增加城市.};


城市必须作为窗口显示出来,路径中的各个点也必须作为窗口显示。

#12


按照6楼的观点,这样设计没有问题。

#13


引用 11 楼 damo_xu 的回复:
引用 7 楼 PcrazyC 的回复:
城市必须作为窗口显示出来,路径中的各个点也必须作为窗口显示。


class x{
};

class y: public x{
private:
    y *abut;//邻接的城市,用链表实现,在构造函数中初始化为NULL,写专门的函数增加城市.
};


X是窗口,Y在X上派生不就可以用窗口显示了吗?而邻接的城市是指针类型,你添加的时候NEW出来不也是窗口吗?

#14


理论上是可以的,但是就是有点不太符合大家的习惯而已

#15


up

#16


城市是个窗口,呵呵有意思。

#17


引用 13 楼 PcrazyC 的回复:
X是窗口,Y在X上派生不就可以用窗口显示了吗?而邻接的城市是指针类型,你添加的时候NEW出来不也是窗口吗?


可能老兄没有理解我的问题: 我的邻接的城市其实就是这么实现的。
关键是路径,一个个路径点是包含在城市里的一个非类成员呢?还是作为一个
单独的class呢(因为也是窗口,就打算继承A类)?


我这两天找了几本书来看,看到The C++ Programming Language Bjarne_Stroustrup上有句话:
"不要从具体的类继承。" 经典!!!而且正好那我这样的反例来说明会产生一个逻辑的回圈,导致各个类关系混乱。

所以我打算改成:不用继承。最小的通用窗口是个具体的类(就是上面的A),其他的城市包含这个类。

#18


按lz的需求,这么设计没什么问题

就像CDialog和CEdit等控件类都是继承自CWnd,我也经常在CDialog里面有CEdit成员,有时也用指针,看你个人爱好了,用成员的时候实例化时自动会分配空间,用指针则自行分配空间实例化。

不过如果按lz的设计这些实例如果都是独立的话,最好用指针;如果非独立的,比如某个城市内“绑定”有某些路径的话,则直接用类对象成员即可,安全且方便。

#19


嗯,比原来的好。。。
但不能骄傲喔,想想有没有更好的^_^

引用 17 楼 damo_xu 的回复:
引用 13 楼 PcrazyC 的回复:
X是窗口,Y在X上派生不就可以用窗口显示了吗?而邻接的城市是指针类型,你添加的时候NEW出来不也是窗口吗? 
 

可能老兄没有理解我的问题: 我的邻接的城市其实就是这么实现的。 
关键是路径,一个个路径点是包含在城市里的一个非类成员呢?还是作为一个 
单独的class呢(因为也是窗口,就打算继承A类)? 


我这两天找了几本书来看,看到The C++ Programming Language Bjarne_Stroustrup上有…

#20


引用 19 楼 ysuliu 的回复:
嗯,比原来的好。。。
但不能骄傲喔,想想有没有更好的^_^

哈哈哈哈哈哈,新年快乐。

引用 18 楼 wiowei 的回复:
按lz的需求,这么设计没什么问题
就像CDialog和CEdit等控件类都是继承自CWnd,我也经常在CDialog里面有CEdit成员,有时也用指针,看你个人爱好了,用成员的时候实例化时自动会分配空间,用指针则自行分配空间实例化。
不过如果按lz的设计这些实例如果都是独立的话,最好用指针;如果非独立的,比如某个城市内“绑定”有某些路径的话,则直接用类对象成员即可,安全且方便。

我其实一直也在想这个问题,肯定还要某些设计类的知识。唉,突然发现:陪伴了我4年的C/C++,我对它其实一无所知。

#21


可以

#22


引用 18 楼 wiowei 的回复:
不过如果按lz的设计这些实例如果都是独立的话,最好用指针;如果非独立的,比如某个城市内“绑定”有某些路径的话,则直接用类对象成员即可,安全且方便。


老兄一眼就看出我想绑定路径,牛!
不过如开始所说,基类就是简单的hwnd,id,都是protected,城市和路径都是继承而来,城市中如果包含路径实例,这样城市的class中的hwnd,id栏位会和路径的hwnd,id栏位重复吧?会不会有些乱?

#23


最好别这样

#24


引用 22 楼 damo_xu 的回复:
引用 18 楼 wiowei 的回复:
不过如果按lz的设计这些实例如果都是独立的话,最好用指针;如果非独立的,比如某个城市内“绑定”有某些路径的话,则直接用类对象成员即可,安全且方便。 
 

老兄一眼就看出我想绑定路径,牛! 
不过如开始所说,基类就是简单的hwnd,id,都是protected,城市和路径都是继承而来,城市中如果包含路径实例,这样城市的class中的hwnd,id栏位会和路径的hwnd,id栏位重复吧?会不会有些乱?

每个类是一个命名域,不同域内的变量名重复没关系,当然你自己要分清楚,比如ID:
class A {
public:
A(int id):ID(id){};
int getID(){return ID;}
protected:
int ID;
};
class Y: public A
{
public:
Y(int id):A(id){}
};

class X: public A
{
private:
Y y;
public:
X(int id,int id_y):A(id),y(id_y){}
int getYID(){return y.getID();}
};
X对象只能用getID来获取自己的ID,而用getYID()来获取成员y的ID

#25



看看设计模式吧
能写一个类不是问题
能写出很多类,而且要把类写好,结合好,还是要看看设计模式的
你的x,y类都是从a继承,同时x里面有组合了y,问题倒是没有问题,类的耦合和类的重叠就让整个类的设计显得很不好了

#26


为了避免相互包含等副作用,最好用指针



class obj 
{

};

class path : public obj
{

};

class city : public obj
{
public :
    vector<path*> vPaths;
};

#27


引用 26 楼 Chiyer 的回复:
为了避免相互包含等副作用,最好用指针
 我也就是想这么写,吼吼。不过好像指针的副作用更大。
引用 24 楼 wiowei 的回复:
每个类是一个命名域,不同域内的变量名重复没关系,当然你自己要分清楚,比如ID:...
 变量名不是问题。
class A {
protected: ID;
...};
关键就是这个ID栏位。X里面有,Y里面也有。
所以让X里面包含Y,总感觉在X里面重复冗余定义了一个ID栏位,总感不爽,
就如同前面几位仁兄和ztz0223回复的那样:
引用 25 楼 ztz0223 的回复:
你的x,y类都是从a继承,同时x里面有组合了y,问题倒是没有问题,类的耦合和类的重叠就让整个类的设计显得很不好了
 

除非把继承看做是为了定义一个新类而避免敲相同的代码:
就是除非上面的代码完全等同于:
-没有 class A
-class Y { private: ID; ...};
-class X { private: ID; Y y; ...};

#28


引用 27 楼 damo_xu 的回复:
关键就是这个ID栏位。X里面有,Y里面也有。 
所以让X里面包含Y,总感觉在X里面重复冗余定义了一个ID栏位,总感不爽, 

这个ID是其成员的ID,何为重复呢?每个对象的ID只有一个,这种设计方法每个X对象总有着自己“独占”的Y对象,何况你的Y是private,也就是说不可能会重复。
我觉得这种思路下的设计就算是用指针也要在X实例化时在构造函数里分配空间实例化成员,还不如直接用类对象做成员更加方便且安全。除非你的Y并不是“绑定”的,比如不是private;不是在X实例化时就固定下来的(需要动态生成);生命周期不是伴随着X对象。

#29


引用 28 楼 wiowei 的回复:
这个ID是其成员的ID,何为重复呢?


那继承就是为了定义一个新类而避免敲相同的代码了吗?:
上面继承A的代码完全等同于:
-没有 class A
-class Y { private: ID; ...};
-class X { private: ID; Y y; ...};

#30



-class A { protected: int ID; };
-class X : public A {};
-class Y { protected: A a; };

如果构造两个class , X和Y有什么不同?好像一样吧?

#31


哦,不一样。
-class A { protected: int ID; };
-class X : public A {}; 
但可以说X就是A吗?就是定义了两个完全相同的类,只是名称不同。

#32


继承是为了“特例化”呀,你的X和Y总会有些跟别人不同的东西吧,拿你的例子来说:
城市X总有城市名、邮编、所处省、人口数等等
街道Y总会有街道名、长度、方位、区域等

基类是为了提取出“共同”的东西,继承类是为了体现“特殊”的东西,你要是X和Y都一样何必要两个类。。跟A一样何必要继承。。

#33


多谢了。
我举这个特殊的例子其实还是理解我原来那个疑问,子类中包含另一个子类,我也像前面几位回答我的网友一样的认为不妥。
原因是:
Y继承A,有了“共同”的东西;(可以表示为:Y是一个大框,套在里面的是小框A)
X继承A,有了“共同”的东西;(可以表示为:X是一个大框,套在里面的是小框A)
然后X再包含Y,怎么表示这个X类呢?(不是说一个object的实现,而只是问怎么表示这个class?)

(应该表示为:大框X里面有一个“共同”部份和一个次大框Y,Y里面还有一个“共同”部份。)

这也就是我们所说的X里面有两个“共同”部份。

#34


引用 33 楼 damo_xu 的回复:
多谢了。 
我举这个特殊的例子其实还是理解我原来那个疑问,子类中包含另一个子类,我也像前面几位回答我的网友一样的认为不妥。 
原因是: 
Y继承A,有了“共同”的东西;(可以表示为:Y是一个大框,套在里面的是小框A) 
X继承A,有了“共同”的东西;(可以表示为:X是一个大框,套在里面的是小框A) 
然后X再包含Y,怎么表示这个X类呢?(不是说一个object的实现,而只是问怎么表示这个class?) 

(应该表示为:大…


这个"共同"的东西只是从数据的角度来说的,具体到继承类可就不是“共同”的了,会被“特殊”化的(内容)

就拿你所说的hwnd和iD来说,X有,Y有,X包含Y,则X中有“双份”,但这双份是“重复”的么?X需要,Y需要,可以单份么?

关键是你包含了Y,到底Y是不是不需要“这份”?如果需要,何来重复?

#35


不止要考虑编译,重在设计

#36


引用 34 楼 wiowei 的回复:
这个"共同"的东西只是从数据的角度来说的,具体到继承类可就不是“共同”的了,会被“特殊”化的(内容)
就拿你所说的hwnd和iD来说,X有,Y有,X包含Y,则X中有“双份”,但这双份是“重复”的么?X需要,Y需要,可以单份么?
关键是你包含了Y,到底Y是不是不需要“这份”?如果需要,何来重复?


吼吼,早上醒来,我也突然想通了这个道理!真是的,何来重复?! 
看来结论可以下了:如果需要,子类可以包含另一个子类。

多谢老兄不厌其烦,送200分,表个心意,以后还应会请教。

并多谢大家了。新年快乐。

#37


晕,每帖只能加分一次,此帖已加过分,不能再加了。
吼吼,wiowei兄,俺欠你一百分。