private 链式多继承以复用代码时碰到的问题

fallening 2010-11-09 12:42:54
大致这样的代码:
s2 在实现自己的算法的时候复用了s1的算法,而s3的算法则要复用s1 s2的算法,在继承的时候出现了问题

struct s1
{
// ...
protected:
int impl( int i )
{
if ( i > 10 )
return method1(i);
return method2(i);
}
private:
int method1( int i )
{
return i*i;
}
int method2( int i )
{
return i+i;
}
};

struct s2 : private s1
{
// ...
protected:
int impl( int i )
{
if ( i < 100 )
return method1(i);
return method2(i);
}
private:
int method1( int i )
{
return s1::impl(i) * i;
}
int method2( int i )
{
return i*i*i;
}
};

struct s3: private s1, private s2
{
public:
int operator()( int i )
{
return impl( i );
}
protected:
int impl( int i )
{
if ( i & 1 )
return method1( i );
return method2( i );
}
private:
int method1( int i )
{
return s1::impl(i) * i;
}

int method2( int i )
{
return s1::impl(i) & s2::impl(i) ^ i;
}
};

int main()
{
int ans = s3()(10);
return ans;
}


编译错误为:
引用
test.cc:44:1: warning: direct base ‘s1’ inaccessible in ‘s3’ due to ambiguity
test.cc: In member function ‘int s3::method1(int)’:
test.cc:60:30: error: cannot call member function ‘int s1::impl(int)’ without object
test.cc: In member function ‘int s3::method2(int)’:
test.cc:65:30: error: cannot call member function ‘int s1::impl(int)’ without object


具体的代码场景在: https://github.com/fengwang/random_variate_generator
中的文件:random_variate_generator / include / vg / distribution / t.hpp
为了实现 t 分布,需要用到正态,X^2和指数分布生成的算法,采用了私有继承产生了错误,因为X^2算法同样复用了正态分布的算法。


...全文
92 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
fallening 2010-11-09
  • 打赏
  • 举报
回复
多谢,我用后一种方法了
虚拟继承不太好
ri_aje 2010-11-09
  • 打赏
  • 举报
回复
编译器说的很清除了,你的s3包含两个s1子对象,因此,对于s1::impl的调用无法决议。如果不能更改继承结构,就只能即用需要虚拟继承了,如下

struct s2 : virtual private s1
struct s3 : virtual private s1, virtual private s2

如果你不喜欢虚拟继承,就的修改继承结构,使得s3中的两个s1能够通过不同继承路径分离出来,最简单的方法是增加一个缓冲的中间类,像下面这样

namespace
{
struct s1_proxy : public s1 { };
}
struct s3 : private s1_proxy, private s2
{
// ...
int method1( int i )
{
return s1_proxy::impl(i) * i;
}
int method2( int i )
{
return s1_proxy::impl(i) & s2::impl(i) ^ i;
}
};

第二种方法经过空基类优化后,应该能够生成和你原来无法通过编译的程序同样的机器代码,因此即兼顾效率又解决问题。
wokonglinglude 2010-11-09
  • 打赏
  • 举报
回复

struct s2 : private s1

struct s3: private s1, private s2

s3里面是不是有了两个s1的子对象

64,643

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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