【发布时间】:2016-04-11 18:37:58
【问题描述】:
假设同一个A类有以下两个版本:
版本 1
class A
{
public:
enum class Retrievable { Integer, String };
A(): m_integer(123), m_string("string") {}
~A() {}
void* get(const Retrievable r)
{
switch (r)
{
case Retrievable::Integer:
return static_cast<void*>(&m_integer);
case Retrievable::String:
return static_cast<void*>(&m_string);
default:
throw;
}
}
private:
int m_integer;
std::string m_string;
};
第 2 版
class A
{
public:
A(): m_integer(123), m_string("string") {}
~A() {}
int getInteger() { return m_integer; }
std::string getString() { return m_string; }
private:
int m_integer;
std::string m_string;
};
就清晰度、效率和可扩展性而言,这两种范式——单个无类型的 get() 函数或单独的显式 get() 函数——哪一个更好?
【问题讨论】:
-
后者。在前者中,您需要同时指定参数
r和容易出错且多余的返回类型。也无法做到virtual。当您以某种方式使用指定类型时,前者很有用,例如dynamic_cast但在这个例子中你没有。 -
不编译的代码比编译的代码快。版本 1 无法编译,因此显然性能更好。等等,什么?如果您想知道选项 1 或选项 2 是否更好,请提供描述您的选项的实际工作代码。因为上述内容没有任何意义——我必须从根本上重写你的一个选项以使其编译,谁知道我是否会以同样的方式重写相同的代码。
-
@Yakk 老实说,我的编码还没有达到可以编译工作示例的程度。但是,由于其他原因,我最终使用了第二种方法。这是一个理论练习,我很想知道答案。我确信我可以得到这样的东西来编译。问题是关于它背后的理论,而不是我发布的具体内容(我认为它至少部分错误)。
-
@frost 除了你掩饰的部分——得到“这样的东西来编译”——对性能有影响。因为生成的代码看起来很少像您发布的那样,至少有 2 或 3 种不同的可能方式。当询问诸如性能之类的问题时,请询问您已编译的代码,而不是不起作用的代码
-
@Yakk 我已经将代码 sn-ps 更新为可以编译和工作的东西。
标签: performance c++11 extensibility