做一个以人类可读的方式将 .NET IL 翻译成 C++ 的实验。
这里是问题所在:C# 允许您解析具有相同方法名称但返回类型不同的多个接口(interface)。 C++ 似乎不支持这一点,但是使用 vTable 无法解析两个接口(interface)(或者我错了吗?)。
我找到了一种使用模板在 C++ 中复制 C# 方法的方法,但想知道是否有一种方法不需要模板来解决相同的问题?模板很冗长,我如果可能,我不希望将它们用于每种接口(interface)类型。
这是 C++ 版本。
template<typename T>
class IMyInterface
{
public: short (T::*Foo_IMyInterface)() = 0;
};
template<typename T>
class IMyInterface2
{
public: int (T::*Foo_IMyInterface2)() = 0;
};
class MyClass : public IMyInterface<MyClass>, public IMyInterface2<MyClass>
{
public: MyClass()
{
Foo_IMyInterface = &MyClass::Foo;
Foo_IMyInterface2 = &MyClass::IMyInterface2_Foo;
}
public: virtual short Foo()
{
return 1;
}
private: int IMyInterface2_Foo()
{
return 1;
}
};
class MyClass2 : public MyClass
{
public: virtual short Foo() override
{
return 2;
}
};
void InvokeFoo(IMyInterface<MyClass>* k)
{
(((MyClass*)k)->*k->Foo_IMyInterface)();
}
void main()
{
auto a = new MyClass2();
InvokeFoo(a);
}
这是 C++ 所基于的 C# 引用源。
interface IMyInterface
{
short Foo();
}
interface IMyInterface2
{
int Foo();
}
class MyClass : IMyInterface, IMyInterface2
{
public virtual short Foo()
{
return 1;
}
int IMyInterface2.Foo()
{
return 1;
}
}
class MyClass2 : MyClass
{
public override short Foo()
{
return 2;
}
}
namespace CSTest
{
class Program
{
static void InvokeFoo(IMyInterface k)
{
k.Foo();
}
static void Main(string[] args)
{
var a = new MyClass2();
InvokeFoo(a);
}
}
}
此 C++ 方法在下面不起作用,但希望它能起作用(它更符合我的要求)。
class IMyInterface
{
public: virtual short Foo() = 0;
};
class IMyInterface2
{
public: virtual int Foo() = 0;
};
class MyClass : public IMyInterface, public IMyInterface2
{
public: virtual short Foo()
{
return 1;
}
private: int IMyInterface2::Foo()// compiler error
{
return 1;
}
};
class MyClass2 : public MyClass
{
public: virtual short Foo() override
{
return 2;
}
};
void InvokeFoo(IMyInterface* k)
{
k->Foo();
}
void main()
{
auto a = new MyClass2();
InvokeFoo(a);
}
最佳答案
问题是您不能仅根据返回类型进行重载。
见
最后一个 stackoverflow 线程指出使用运算符可以实现重载。
struct func {
operator string() { return "1"; }
operator int() { return 2; }
};
int main() {
int x = func(); // calls int version
string y = func(); // calls string version
double d = func(); // calls int version
cout << func() << endl; // calls int version
func(); // calls neither
}
不过你不能说出它们的名字,这很快就会变成一团糟。
参数列表必须更改。 Victor Padureau 建议使用 void 返回类型并将值的类型作为引用传递给方法中的值,这将起作用。您还可以更改不同类型的方法名称。
class my_interface
{
public:
virtual short foo_short() = 0;
};
class my_interface2
{
public:
virtual int foo_int() = 0;
};
class my_class : public my_interface, public my_interface2
{
public:
short foo_short() override
{
return 1;
}
int foo_int() override
{
return 1;
}
};
class my_class2 : public my_class
{
public:
virtual short foo_short() override
{
return 2;
}
};
void InvokeFoo(my_interface* k)
{
short result = k->foo_short();
std::cout << result << std::endl;
}
void main()
{
auto a = new my_class2();
InvokeFoo(a);
}
关于c# - 仅返回类型不同的 C++ 多个接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54194130/
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案