我有以下C++设计问题,非常感谢任何建议/解决方案。
请注意,我的背景不是计算机科学,因此我可能缺少一些明显的解决方案。
我通常在代码中分离关键组件的方式是通过抽象类和纯虚函数定义接口(interface)。
范例1:
class B
{
public:
virtual double f( double x ) = 0;
};
class D1 : public B
{
public:
double f( double x ) const
{
return 0.0;
}
};
class D2 : public B
{
public:
double f( double x ) const
{
return 1.0;
}
};
class F {
public:
virtual double f( double x ) = 0;
};
class G {
public:
virtual double g( double x ) = 0;
};
class H {
public:
virtual double h( double x ) = 0;
};
class N {};
template<class T1, class T2=N, class T3=N>
class Feature : public T1 , public T2 , public T3
{
};
template<class T1, class T2>
class Feature<T1,T2,N> : public T1, public T2
{
};
template<class T1>
class Feature<T1,N,N> : public T1
{
};
//Supp for Supports/Implements
class SuppFandG : public Feature<F,G>
{
public:
double f( double x ) { return 0.0; }
double g( double x ) { return 1.0; }
};
class SuppFandH : public Feature<F,H>
{
public:
double f( double x ) { return 0.0; }
double h( double x ) { return 1.0; }
};
class SuppFandGandH : public Feature<F,G,H>
{
public:
double f( double x ) { return 0.0; }
double g( double x ) { return 1.0; }
double h( double x ) { return 2.0; }
};
int main()
{
Feature<F,G>* featureFandGPtr;
Feature<F,H>* featureFandHPtr;
Feature<H,F>* featureHandFPtr;
Feature<F,G,H>* featureFandGandHPtr;
SuppFandGandH suppFandGandH;
featureFandGandHPtr = &suppFandGandH;
//featureFandGPtr = featureFandGandHPtr; //Illegal. static_cast illegal too.
//the reason to do this is that I would like to pass a pointer to an object
//of type Feature<F,G,H> to a function (or constructor) that expects a pointer to Feature<F,G>
featureFandGPtr = reinterpret_cast< Feature<F,G>* >( featureFandGandHPtr );
featureFandHPtr = reinterpret_cast< Feature<F,H>* >( featureFandGandHPtr );
featureHandFPtr = reinterpret_cast< Feature<H,F>* >( featureFandGandHPtr );
featureFandGPtr->f( 1.0 );
featureFandGandHPtr->h( 1.0 );
}
//This will not work, Visual studio 2008 professional crash.
template<class T1, class T2=N, class T3=N>
class Feature : public Feature<T1,T2> , public Feature<T1,T3> , public Feature<T2,T3>
{
};
template<class T1, class T2>
class Feature<T1,T2,N> : public Feature<T1>, public Feature<T2>
{
};
template<class T1>
class Feature<T1,N,N> : public T1
{
};
最佳答案
现在,这是一个有趣的问题!
显而易见的(简单)解决方案是使模板疯狂。如果每个功能仅需要一个接口(interface)(而不是一个确定的类型),则可以减轻您的大部分顾虑。但是,当然这在依赖方面有其自身的惩罚,您在第4点中拒绝了该解决方案。
动态转换?
struct Feature { virtual ~Feature() {} };
class F: public Feature {};
class G: public Feature {};
F和G的类class Impl: public F, public G {};
void method(Feature const& i)
{
F const& myF = dynamic_cast<F const&>(i);
G const& myG = dynamic_cast<G const&>(i);
myF.f(2.0);
myG.g(2.0);
}
namespace detail
{
void methodImpl(F const& f, G const& g);
}
template <class T>
void method(T const& t)
{
detail::methodImpl(t,t);
}
BostonLogan的方法与更好的接口(interface)结合在一起。没有用户代码应该提及detail命名空间(易于测试),如果这样,则可以确保没有人使用两个不同的对象来调用methodImpl。T可能是从H或Z继承的,您不在乎,只要它从F和G继承,则代码将编译method),但这是非模板方法的单线转发器,该方法可以进行实际的繁重工作。 methodImpl实际上有2个对同一对象的引用,这可能会给将来带来麻烦。Feature应该声明一个转发器class F
{
public:
void f(double d);
void f2(double d, double e) const;
};
class FForwarder
{
public:
FForwarder(F& f) : m_object(f) {}
void f(double d) { m_object.f(d); }
void f2(double d, double e) const { m_object.f(d,e); }
private:
F& m_object;
};
struct nil {};
template <class Head, class Tail>
struct Aggregator: Head, Aggregator<Tail::head, Tail::tail>
{
typedef Head head;
typedef Tail tail;
template <class T>
Aggregator(T& t) : Head(t), Aggregator<Tail::head, Tail::tail>(t) {}
};
template <class Head>
struct Aggregator<Head,nil> : Head
{
typedef Head head;
typedef nil tail;
template <class T>
Aggregator(T& t) : Head(t) {}
};
template <>
struct Aggregator<nil,nil>
{
typedef nil head;
typedef nil tail;
template <class T>
Aggregator(T&) {}
};
int method(Aggregator<FForwarder, Aggregator<GForwarder, HForwarder> >& fgh);
namespace detail
{
typedef Aggregator<FForwarder, Aggregator<GForwarder, HForwarder> > methodImplArg;
int methodImpl(methodImplArg& arg);
}
template <class T>
int method(T& t)
{
detail::methodImplArg arg = detail::methodImplArg(t);
//named temporary because it is passed by reference to non-const
return detail::methodImpl(arg);
// forward the result as well
};
methodImpl相当整齐地传递2个参数的问题,尽管它确实需要额外的工作...我想应该有一个更简单的方法,但还不能查明。
关于c++ - 如何为任意(但在编译时定义)功能支持定义抽象基类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1723796/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我刚刚为fedora安装了emacs。我想用emacs编写ruby。为ruby提供代码提示、代码完成类型功能所需的工具、扩展是什么? 最佳答案 ruby-mode已经包含在Emacs23之后的版本中。不过,它也可以通过ELPA获得。您可能感兴趣的其他一些事情是集成RVM、feature-mode(Cucumber)、rspec-mode、ruby-electric、inf-ruby、rinari(用于Rails)等。这是我当前用于Ruby开发的Emacs配置:https://github.com/citizen428/emacs
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>