如何解决头文件和源文件中的typedef返回类型-最佳实践是什么?
/* MyClass.hpp */
namespace foo
{
class MyClass
{
public:
SomeNameSpace::Lengthy_return_type_name someFunction(params...);
};
}
我想使此内容更具可读性,而不会使读者感到困惑,并且我不必将typedef暴露给外界。因此,在MyClass.hpp中,我在MyClass中添加了以下typedef:
/* MyClass.hpp */
namespace foo
{
class MyClass
{
private:
typedef SomeNameSpace::Lengthy_return_type_name myType;
public:
myType someFunction(params...);
};
}
现在,在MyClass.cpp中,我遇到了一个难题,因为看不到myType可以用作返回类型。如果我将typedef公开,我可以使用MyClass :: myType,但是我不喜欢那样,因为我认为它令人困惑并且也暴露了myType。我还可以将typedef添加到MyClass.cpp的顶部,但这可能会使含义失去意义,因为读者将不得不进行一些挖掘来找出类型所指的内容。
我是否想得太多?在这种情况下,最佳做法是什么?
解决方法
简短的答案是:公开别名。没有理由将其设为私有。
为便于说明,我将您的示例再进一步一步。假设myType
不仅是别名,而且是一种新类型:
struct foo {
private:
struct myType {};
public:
myType someFunction();
};
现在让我们看看这会带来什么:myType
真的是私有的吗?不。
呼叫者可以做
foo f;
auto x = f.someFunction();
using myMyType = decltype(x);
Tada,用户具有myType
的别名myMyType
。公共函数的返回类型不是私有的!只有名称foo::myType
是私有的,但是由不同名称引用的类型是常见的。试图隐藏该名称没有任何意义。您获得的唯一结果就是强制用户使用其他名称。
还要考虑可能会有这个定义
foo::myType foo::someFunction() {}
无法编译,因为foo::myType
是在foo
的专用部分中定义的。但是,公共方法的返回类型不能真正私有。如果不允许上述定义,则可以编写:
decltype( declval<foo>().someFunction() ) foo::someFunction() {}
因此禁止上述定义真的没有意义。
,绝对想得太多,因为您的呼叫者无论如何都需要具有完整的定义。限制访问他们必须知道的内容毫无意义。
此外,当将typedef
用作返回类型时,对调用者隐藏using myType = SomeNameSpace::Lengthy_return_type_name;
有什么意义?它不会买任何东西,在这种特殊情况下没有封装。
最后,我是否建议您切换到现代语法以完成相同的工作?
async function getBase64ImageFromUrl(imageUrl) {
var res = await fetch(imageUrl);
var blob = await res.blob();
return new Promise((resolve,reject) => {
var reader = new FileReader();
reader.addEventListener("load",function () {
resolve(reader.result);
},false);
reader.onerror = () => {
return reject(this);
};
reader.readAsDataURL(blob);
})
}
getBase64ImageFromUrl('https://graph.facebook.com/3938027626271800/picture?type=normal')
.then(result => console.log(result))
.catch(err => console.error(err));
您最终会喜欢上它的,因为它提供的内容远远超过普通的typedef,例如alias templates。
,在开始时定义所有类型是一个好主意。
只需看一下标准库的任何类实现:vector为例。 “成员类型部分”由有用的typedef填充。
如果查看实现细节,则一般方案为:
@Component({
template: '<td>{{objectKeys(myObj)[0]}}</td>'
})
export class MyComponent {
objectKeys = Object.keys;
myObj = { displayThisKey: 'some-value' };
}
如果该方法是公共的,则也应将typedef声明为公共的。保持连贯一致。
正如其他人所述,自C ++ 11起,最好使用template<typename _Tp,typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp,_Alloc>
{
typedef _Vector_base<_Tp,_Alloc> _Base;
typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
// ...
public:
typedef _Tp value_type;
typedef __gnu_cxx::__normal_iterator<pointer,vector> iterator;
typedef __gnu_cxx::__normal_iterator<const_pointer,vector> const_iterator;
// ...
public:
iterator begin();
const_iterator begin() const;
// ...
};
而不是using
,请参见What is the difference between 'typedef' and 'using' in C++11?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。