2014-01-05 25 views
1

鉴于原型:重载函数时使用临时对象作为参数是否是一种好的做法?

void foo(int i); 
void foo(int i, const std::string &s); 

实现:

void foo(int i) 
{ 
    foo(i, std::string()) ; 
    //! ^^^^^^^^^^^^^ ^here? 

    // nothing more. 

     } 
//! ^here? 

void foo(int i, const std::string &s) 
{ 
    //do something 
} 

哪里由std::string()创建的临时对象走出去的范围有多大?以这种方式重载函数是一种很好的做法吗?

更新:

让我解释的情况一点点。作为练习,我正在尝试编写一个类似std::vector的类,而不使用模板。它唯一的类型是std::string。班级正文可在another question找到。

在实现resize()成员函数,我发现std::vector似乎使用了两个功能:

所以我不知道我是否应该使用的,而不是单一的一个两个功能。

+0

如果不理解预期的语义,真的不可能给出一个好的答案。如果两个'foo'都做同样的事情,给它们起同样的名字是有道理的,那么为什么只需要更少的参数就需要调用更多的东西,然后做更多的东西呢?这些东西是微不足道的(日志?)还是界面的一个可见部分,这样一个'foo'在外部就可以理解为不同于另一个? –

+0

随着编辑,关于生命期的问题没有多大意义。 – Mat

+0

@DavidSchwartz你好我已经更新了线程。希望它能让情况更清楚。 –

回答

2

我不认为这是不好的做法,特别是如果你使foo(int i)内联。这是最好的时候,我能想到的理由:当您创建的指针的功能,如果你声明的第二个参数默认情况下,你只能有指针接受2个参数的功能。

临时值活着才有作为函数调用的参数。

inline void foo(int i) 
{ 
    foo(i, std::string()); 
} 

void foo(int i, const std::string &s) 
{ 
    //do something 
} 
+0

为什么内联?让它更快? –

3

不,这不是一个好的做法,至少在这个特定的情况下。使用一个单一的功能,并为参数的默认值,而不是两个功能,其中一个似乎只存在提供一个默认的说法:

void foo(int i, const std::string &s = "") 
{ 
    //do something 
} 
+0

在这种情况下似乎确实如此。 – meagar

+0

你可能想说'std :: string()'而不是'''',以防万一实施发生为空文本分配内存。 – Mehrdad

+0

@meagar嗨!我更新了线程。希望它能让情况更清楚。 –

1

唯一的“危险”,在传递一个暂时的const&发生,如果该函数创建一个生存函数调用本身,其存储本身const&的对象。

认为

class A 
{ 
    const string& a; 
public: 
    A(const string& a) :a(a) {} 
    void act() { .... /* use a */ } 
}; 

A* foo(const string& s) 
{ return new A(s); } 

int main() 
{ 
    A* pa = foo(string()); 
    //here, pa->act() will act on a dangling reference. 
} 

如果您foo功能只是使用字符串,但不保留供以后使用的参考,通过临时是绝对安全的。

如果发生这种情况使用“开机功能”或默认临时值使得对生成的代码没有什么区别。

在这一点上,使用一个或两个函数更多的是风格和机会问题:在进一步开发过程中,两个函数有多少区别?

如果答案是“没有:第二个功能是非常频繁的情况下,只需定义(或快捷方式)”比默认值完美地完成这项工作。

如果答案是“让我们回落到其他功能现在,后来更具体”,然后的两个函数被preferrable。

默认值都是然而,这不是的情况下,有机会的功能是模板,你想类型推演工作:

template<class C, class T> 
void fn(int i, basic_string<C,T>& s = ????); 

你不能使用的std :: string(),因为它不会为C其他工作比char,并且不能使用std::basic_string<C,T>(),因为它不允许在调用fn(5)时知道C和T应该是什么。

所以,你会最终了

void fn(int i) { fn(i,string()); } 

相关问题