我可以制作一个对象方法,如果单独调用它会修改自身,但如果在复制初始化期间调用 return 一个新对象吗?
Can I make an object method that will modify itself if called alone but return a new object if called during copy initialization?
我正在编写自定义日期时间 class。是否可以这样做:
datetime mydate;
mydate.to_utc(); // object modifies itself
但是当这样调用时:
datetime mynewdate = mydate.to_utc();
或者像这样:
datetime mynewdate(mydate.to_utc());
我不希望 mydate.to_utc() 修改自身,只希望 initialize/construct mynewdate 的值为 mydate.to_utc();
谢谢,
虽然我同意其他人的观点,将 API 这样混合通常是个坏主意,但无论如何有一个简单的方法可以解决它:使非 returning 函数不 return 任何东西(当然)并使 returning 函数 const
合格。成员函数const
限定是函数签名的一部分,可以用来区分重载。
像这样:
class datetime
{
public:
// ...
// This function modifies the current object in place
void to_utc();
// This function returns a new datetime object
datetime to_utc() const;
};
类似于上面的代码在 "setters" 和 "getters" 中并不少见,但是编译器能够区分 "setter" 和 "getter" 也有参数("setter" 有参数,"getter" 没有)。
"setters" 和 "getters" 与上述代码之间的区别是(如前所述)编译器可以通过以下方式区分 "setter" 和 "getter"争论。这不可能与我对所问问题的上述解决方案有关。并且可能导致构建错误,如评论中所述。提供的解决方案在某些情况下可能有效,但在其他情况下无效,因此使用时应谨慎。
使用 C++ 无法实现您想要实现的目标:重载解析完全独立于 return 类型 – 以及是否评估此类型。
所以这两个不同的重载
void to_utc(); // self-modifying
datetime to_utc(); // returning new object
永远都是模棱两可的。
现在您可以尝试通过将其中之一设为常量(如Some programmer dude )来区分它们,但这不会产生您想要的效果:
datetime dt0;
datetime dt1 = dt0.to_utc();
dt0
不是 const,因此重载决策也会 select 非常量重载,并且您最终会 dt0
再次修改自身。更糟糕的是:由于 selected 重载 returns void
,代码甚至无法编译。您现在可以通过适当地转换来解决这个问题:
datetime dt1 = const_cast<datetime const>(dt0).to_utc();
不过,如果这在问题的意义上,我有很多疑问......
实际上剩下的是重命名两个重载之一:
void to_utc(); // self-modifying
datetime as_utc() const; // creating a copy
// ^^^^^
// independent from given problem: the function won't modify 'this' object
// so having it const still is a good idea...
或者你有一个重载作为独立的(或静态的;不过我更喜欢前者)函数,e。 g.:
datetime to_utc();
void to_utc(datetime&);
我个人会保留两个不同名称的成员函数,但是...
我通常最终做的是提供两个功能:
struct datetime
{
// mutate the object itself
void apply_to_utc();
// return the new object
auto to_utc() const -> datetime;
};
这使得调用哪个函数以及调用者的意图变得更加清晰。
我正在编写自定义日期时间 class。是否可以这样做:
datetime mydate;
mydate.to_utc(); // object modifies itself
但是当这样调用时:
datetime mynewdate = mydate.to_utc();
或者像这样:
datetime mynewdate(mydate.to_utc());
我不希望 mydate.to_utc() 修改自身,只希望 initialize/construct mynewdate 的值为 mydate.to_utc();
谢谢,
虽然我同意其他人的观点,将 API 这样混合通常是个坏主意,但无论如何有一个简单的方法可以解决它:使非 returning 函数不 return 任何东西(当然)并使 returning 函数 const
合格。成员函数const
限定是函数签名的一部分,可以用来区分重载。
像这样:
class datetime
{
public:
// ...
// This function modifies the current object in place
void to_utc();
// This function returns a new datetime object
datetime to_utc() const;
};
类似于上面的代码在 "setters" 和 "getters" 中并不少见,但是编译器能够区分 "setter" 和 "getter" 也有参数("setter" 有参数,"getter" 没有)。
"setters" 和 "getters" 与上述代码之间的区别是(如前所述)编译器可以通过以下方式区分 "setter" 和 "getter"争论。这不可能与我对所问问题的上述解决方案有关。并且可能导致构建错误,如评论中所述。提供的解决方案在某些情况下可能有效,但在其他情况下无效,因此使用时应谨慎。
使用 C++ 无法实现您想要实现的目标:重载解析完全独立于 return 类型 – 以及是否评估此类型。
所以这两个不同的重载
void to_utc(); // self-modifying
datetime to_utc(); // returning new object
永远都是模棱两可的。
现在您可以尝试通过将其中之一设为常量(如Some programmer dude
datetime dt0;
datetime dt1 = dt0.to_utc();
dt0
不是 const,因此重载决策也会 select 非常量重载,并且您最终会 dt0
再次修改自身。更糟糕的是:由于 selected 重载 returns void
,代码甚至无法编译。您现在可以通过适当地转换来解决这个问题:
datetime dt1 = const_cast<datetime const>(dt0).to_utc();
不过,如果这在问题的意义上,我有很多疑问......
实际上剩下的是重命名两个重载之一:
void to_utc(); // self-modifying
datetime as_utc() const; // creating a copy
// ^^^^^
// independent from given problem: the function won't modify 'this' object
// so having it const still is a good idea...
或者你有一个重载作为独立的(或静态的;不过我更喜欢前者)函数,e。 g.:
datetime to_utc();
void to_utc(datetime&);
我个人会保留两个不同名称的成员函数,但是...
我通常最终做的是提供两个功能:
struct datetime
{
// mutate the object itself
void apply_to_utc();
// return the new object
auto to_utc() const -> datetime;
};
这使得调用哪个函数以及调用者的意图变得更加清晰。