2011-03-31 26 views
2
#include <iostream> 
using namespace std; 

typedef int num; 

int main() { 
    num a, b; 
    cin >> a >> b; 
    cout << a + b; 
    return 0; 
} 

这样,如果我必须通过更改一行代码将其更改为浮点数或复数。是typedef是否有助于提高可扩展性

这是一个很好的做法吗?

+5

这似乎是一个很危险的事情。 – asawyer 2011-03-31 15:30:39

+0

如果你的论点是你可以改变类型为'unsigned'或'long'或另一种整数类型,那么你可能会更安全。从整数变为浮点是一个更大的变化,相应地不太安全。 – 2011-03-31 15:37:08

回答

3

我不会说

typedef int num; 

因为num并不真正意味着更多,而不是传授更多信息,这种风格是非常有用的。但是,你做什么,看到的是分离的类型,例如像

typedef long time_t 

在这种情况下,在标准库,而不是使用长代表秒数,您可以使用time_t。该标准允许实现者在参数(包括浮点)内为其选择不同的类型。

所以,我会在减少或指定类型的含义时使用typedef,并且有几个选择可以满足该定义,并且您不希望任何人依赖选择,而仅仅是规范。

3

更有趣的问题是:为什么你想改变变量的类型?

因为你必须记住,甚至像int和float这样的数值变量在某些情况下也会有不同的表现,并且无论什么时候将它用作这种“通用”变量,都需要考虑这些情况。因此,我倾向于这样说:不,它不是,作为副作用(特别是一旦项目变得比仅仅是一个hello世界更大一点;))发挥太大的作用,你可以改变类型

+0

所以,如果我想扩展这个“计算器”的能力,我会更好用一个普通的抽象类的int浮动等包装类? – Atomble 2011-03-31 15:37:24

+2

那么既然我们在谈论C++,那么您就有了重载函数和/或使用模板的绝佳机会。我认为这是最好的选择。 – Chris 2011-03-31 15:39:51

2

这听起来像是你在寻找templates

+0

正如在这个例子中,我希望“计算器”中的所有数字具有相同的类型。不会模板让事情变得更复杂? (例如,类型转换?) – Atomble 2011-03-31 15:42:53

+0

不,模板允许您定义一个算法,而不必提交涉及的所有类型的数据。然后,您可以用不同的方式以不同的方式实例化模板,例如,浮动,复杂等。听起来非常适合你的计算器。我不知道你的意思是通过类型转换。 – 2011-03-31 15:44:42

+0

所以制作一个添加数字的模板? – Atomble 2011-03-31 15:51:36

1

理论上,从学术的角度来看,答案可能是“是”。但在现实世界中,我发现答案几乎总是“不”,这就是为什么。

你说你的理想将能够做一个1行代码更改从int s切换到float s例如,并完成。这很好,但由于某种原因,这几乎从来没有可能实现。

考虑一下你的实际例子。如果你有这样的代码:

typedef int num; 
... 
num = 42; 
... 
if(42 == num) 
    // MAGIC HAPPENS 

...然后将其更改为:

typedef float num; 

...代码很可能会编译,但它无法正常工作。那是因为你不能将浮点数与一个常量变量相比较。花车是不精确的,42f的实际表示可能类似41.99999999999999,然后if(42f == num)将返回false。

其他例子无处不在。例如,在STL集合类中使用typedef是最好的例子。如果你有这样的:

typedef vector<string> strings; 
strings my_strings; 
... 
my_strings.find("hello"); 

...你不能只是改变的typedef是list<string>因为list没有一个find成员函数。

根据我的经验,typedef对保存输入非常有用,从而节省了潜在的错误,并且使代码更具可读性。例如:

for(strings::iterator it = my_strings.begin(); it != my_strings.end(); ++it) 

...可以说是比更易读:

for(vector<string>::iterator it = my_strings.begin(); it != my_strings.end(); ++it) 

...特别是当容器的类型变得越来越复杂。

+0

对于不断变化的实现和宽松的规范,*总是* true。接口原则上遭受同样的问题,但他们被称为主的新来临。我*仍*本能地同意你的评估,但我认为这不完全准确。 – 2011-03-31 17:58:39

1

在某些情况下,typedef很重要。有一些技术,如Policy Clone。另外看看在GotW #46由Herb萨特给出的理由:

Typeability
短的名字

可读性

typedef int (*Func)(int*); 
Func t(int); 

而不是

int (*t(int))(int*); 

便携

#if defined USING_COMPILER_A 
    typedef __int32 Int32; 
    typedef __int64 Int64; 
#elif defined USING_COMPILER_B 
    typedef int  Int32; 
    typedef long long Int64; 
#endif 
相关问题