3

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

Hossein
  • 4,097
  • 2
  • 24
  • 46
nitin_cherian
  • 6,405
  • 21
  • 76
  • 127

3 Answers3

10

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
};
Peter G.
  • 14,786
  • 7
  • 57
  • 75
2

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.

2

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;
}
ComfortablyNumb
  • 3,391
  • 2
  • 14
  • 15