禁止 C++ 自动提供的功能;编译器
Scott Meyers 在他的《Effective C++》一书中说,
要禁止编译器自动提供的功能,请声明 相应的成员函数为 private 并且不给出 那么如果有人不经意地调用了一个,他们就会 在链接时出现错误。
我尝试编写一个示例程序来实现斯科特试图解释的内容。即使成员函数被声明为 public 并且没有给出任何实现,我也可以实现相同的目标。当我尝试从另一个对象初始化一个对象时,我的情况也发生了链接错误。所以我不明白为什么斯科特强调需要将成员函数声明为私有?
我的示例程序如下所示:
#include <iostream>
using namespace std;
class Unique
{
private:
int num;
public:
Unique(int x)
{
num = x;
}
Unique(const Unique &obj);
Unique& operator =(const Unique &obj);
void disp(void)
{
cout << "num = " << num << "\n";
}
};
int main()
{
Unique ob1(3);
Unique ob2(ob1);
ob1.disp();
ob2.disp();
return 0;
}
我收到以下链接错误:
/tmp/ccXfqSqE.o(.text+0x135): 在函数
main' 中: : 未定义 引用
Unique::Unique(Unique const&)'collect2: ld 返回 1 退出状态
Scott Meyers in his book "Effective C++" says,
To disallow functionality automatically provided by compilers, declare
the corresponding member functions private and give no
implementations.Then if somebody inadvertently calls one, they will
get an error at link-time.
I tried to write a sample program for achieving what Scott was trying to explain. I could achieve the same even when the member function was declared public
and given no implementation. The link-error occurred in my case also when i tried to initialize an object from another object. So i do not understand why Scott is emphasizing on the need of member function to be declared private
?
My sample program is written below:
#include <iostream>
using namespace std;
class Unique
{
private:
int num;
public:
Unique(int x)
{
num = x;
}
Unique(const Unique &obj);
Unique& operator =(const Unique &obj);
void disp(void)
{
cout << "num = " << num << "\n";
}
};
int main()
{
Unique ob1(3);
Unique ob2(ob1);
ob1.disp();
ob2.disp();
return 0;
}
I get the following link-error:
/tmp/ccXfqSqE.o(.text+0x135): In function
main': : undefined
Unique::Unique(Unique const&)' collect2: ld returned 1
reference to
exit status
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
编译器错误比链接错误更清晰且更早发生(这在从大量源文件编译的大型项目中更为明显)。大多数时候它们也更容易阅读。将成员声明为私有会引发编译错误,因此优先于保留成员未定义以禁止它们。
正如 Baptiste 指出的,在 C++11 中,有更好的 delete 关键字可用于禁止编译器生成的成员:
Compiler errors are clearer and happen earlier (this is more pronounced in big projects ccompiled from a lot of source files) than link errors. They are also easier to read most of the time. Declaring members private provokes compile errors and is therefore preferred over leaving members undefined to disallow them.
As Baptiste notes, in C++11 there is the even better delete keyword available for disallowing compiler-generated members:
如果您将它们声明为私有,那么编译器将在检测到有人试图调用它们时立即停止,无论该函数是否实际定义(因为它们是不允许的)。
通过将它们声明为公共,那么您必须等到链接器阶段才能得到错误,因为它应该是合法的调用,但缺少定义。
If you declare them private then the compiler will stop as soon as it detects someone trying to call them irrespective of whether or not the function is actually defined (since they aren't allowed).
By declaring them public then you have to wait until the linker stage to get your error since it should be a legal call but has a missing definition.
Scott 试图阻止有人调用构造函数并在链接时出错。这正是您遇到的情况。在编译时发现问题比在链接时发现问题要便宜。
顺便说一句,对于 C++11,我们知道有官方方法来阻止编译器为我们生成函数。
Scott is trying to prevent somebody from calling a constructor and getting error at link-time. This is exactly the case you are running into. It's cheaper to spot the issue at compile time than at link-time.
By the way, with C++11, we know have official way to prevent the compiler from generate functions for us.