禁止 C++ 自动提供的功能;编译器

发布于 2024-12-17 03:12:13 字数 970 浏览 0 评论 0原文

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
reference to
Unique::Unique(Unique const&)' collect2: ld returned 1
exit status

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

执笏见 2024-12-24 03:12:13

编译器错误比链接错误更清晰且更早发生(这在从大量源文件编译的大型项目中更为明显)。大多数时候它们也更容易阅读。将成员声明为私有会引发编译错误,因此优先于保留成员未定义以禁止它们。

正如 Baptiste 指出的,在 C++11 中,有更好的 delete 关键字可用于禁止编译器生成的成员:

class A
{
     A(constA&) = delete; // copy construction is not allowed
};

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:

class A
{
     A(constA&) = delete; // copy construction is not allowed
};
So要识趣 2024-12-24 03:12:13

如果您将它们声明为私有,那么编译器将在检测到有人试图调用它们时立即停止,无论该函数是否实际定义(因为它们是不允许的)。

通过将它们声明为公共,那么您必须等到链接器阶段才能得到错误,因为它应该是合法的调用,但缺少定义。

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.

陈年往事 2024-12-24 03:12:13

Scott 试图阻止有人调用构造函数并在链接时出错。这正是您遇到的情况。在编译时发现问题比在链接时发现问题要便宜。

顺便说一句,对于 C++11,我们知道有官方方法来阻止编译器为我们生成函数。

class Unique{
public:
    Unique() = delete;
}

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.

class Unique{
public:
    Unique() = delete;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文