0

I have confusion after reading from some places.

I'm doing example from this page let's say there's a class(Book) which has an object(Author) as one of its member. Here's the constructor:

Book::Book(string name, Author author, double price, int qtyInStock)
      : name(name), author(author) {   **// Must use member initializer list to construct object**
   // Call setters to validate price and qtyInStock
   setPrice(price);
   setQtyInStock(qtyInStock);
}

I tried to declare the object author inside the constructor instead of initializer lisr. It gave me error. no matching function to call Author::Author() --> which is the default constuctor of Author.


After reading from these stackoverflow posts : this1 and this2 What I understand is that, summarizing from those 2:

  • an object is considered & must be fully initialised when execution enters the body of the constructor

  • An object has all of its members initialised in the initialisation list. Even if you do not explicitly initialise them there, the compiler will happily do so for you

  • native types like int or double do have a default constructor

So from all of those above, what I understand is a user defined object/class DOES NOT automatically have DEFAULT CONSTRUCTOR, unlike the primitive types. That's why it gives error, if I do not use member initializer list (which calls copy constructor) , cause the compiler tries to initialize it using default consturctor which it(user defined class) does not have.

And so possible solutions are: define a default constructor for the class, or use member initializer


AND THEN I read this post on stackoverflow saying that: "How Many default methods does a class have?" and the answer mentions that It HAS DEFAULT CONSTRUCTOR

1. If it has default consturctor, Why does my first case( the book and author classes) give error?

Also I read from this page, lets say I defined a class Point before, then page wrote:

Point p1;       // **Invoke default constructor**
                // OR Point p1 = Point(); NOT Point p1();

2. So when we declare like above, does it INVOKE DEFAULT CONSTRUCTOR? Why it does not give an error if so? I thought a class does not have a default constructor?

Appreciate if you can help me to clarify things here, and answer the two questons above (italic)

Community
  • 1
  • 1
mon
  • 641
  • 1
  • 7
  • 14
  • You'll need to post your code, including the `Author` class definition. See here for instructions: http://stackoverflow.com/help/mcve – xaxxon Oct 06 '16 at 06:28
  • 1
    "*I thought a class does not have a default constructor?*" You should go through the reasoning that led you to this conclusion. Therein you will find a flaw. As it stands, your question doesn't make much sense. – juanchopanza Oct 06 '16 at 06:28
  • @xaxxon the Author class definition is in the link that I mentioned https://www.ntu.edu.sg/home/ehchua/programming/cpp/cp3_OOP.html – mon Oct 06 '16 at 06:31
  • @juanchopanza I went through the reasoning if you read my post from the beginning. – mon Oct 06 '16 at 06:32
  • I did read the post. Or did you mean "*I thought **this** class doesn't have a default constructor*?" – juanchopanza Oct 06 '16 at 06:33
  • @juanchopanza Because if it has default constructor: then first case (book and author) will not give error even if I do not use member initializer list for author, cause the compiler can automatically declare it by calling the default consturctor for author. – mon Oct 06 '16 at 06:35
  • So maybe that particular class doesn't have a default constructor (or is not default constructible) but others do? – juanchopanza Oct 06 '16 at 06:36
  • @juanchopanza A class will have default constructor if I manually define it(default constructor). Is that correct? So if I do not manually define default constructor, a class will not have default constructor... – mon Oct 06 '16 at 06:38
  • The first sentence is correct. The second one not. Maybe read up on "special member functions" and what the compiler does for you. – juanchopanza Oct 06 '16 at 06:39
  • @juanchopanza Can you please help to correct the statement and clarify it? – mon Oct 06 '16 at 06:40
  • 1
    @mon Here's a [related Q/A](http://stackoverflow.com/questions/4981241/no-default-constructor-exists-for-class). – juanchopanza Oct 06 '16 at 06:42

2 Answers2

1

The full answer is big, and is presented here:

http://en.cppreference.com/w/cpp/language/default_constructor

If you specifically make one, there is always a default constructor. This includes constructors that MAY accept parameters but don't have to - constructors with default parameters and variadic templates can both be default constructors.

If you mark it as = delete then it will never have one.

Otherwise, if no user-provided constructors are present the compiler will try to make one for you except for in certain circumstances (fully listed in the link above in the Deleted implicitly-declared default constructor section)

  • T has a member of reference type without a default initializer.

  • T has a const member without user-defined default constructor or a default member initializer (since C++11).

  • T has a member (without a default member initializer) (since C++11) which has a deleted default constructor, or its default constructor is ambiguous or inaccessible from this constructor.

  • T has a direct or virtual base which has a deleted default constructor, or it is ambiguous or inaccessible from this constructor.

  • T has a direct or virtual base which has a deleted destructor, or a destructor that is inaccessible from this constructor.

  • T is a non-union class with a variant member M with a non-trivial default constructor, and no variant member of the anonymous union containing M has a default member initializer.

and some additional rules for union types.

tl;dr: it's complicated.

xaxxon
  • 19,189
  • 5
  • 50
  • 80
  • When we declare Point p1; // Invoke default constructor // OR Point p1 = Point(); NOT Point p1(); It says that it will invoke the default consturctor Point(), but Point has its own consturctor? – mon Oct 06 '16 at 06:47
  • It is in the link that I mentioned https://www.ntu.edu.sg/home/ehchua/programming/cpp/cp6_Inheritance.html – mon Oct 06 '16 at 06:51
  • I'm not willing to trust that the code you're actually compiling is the same as what is in the link. You need to provide code that reproduces the issue. – xaxxon Oct 06 '16 at 06:52
  • If Point has its own constructor which needs two arguments, calling default consturctor like Point() will give error right? – mon Oct 06 '16 at 06:53
  • for the Point , I'm not compiling. I'm just reading from the link. And I want to know why I can do Point point; just like that ,if my constructor actually needs argument. Won't that give error? – mon Oct 06 '16 at 06:57
  • Because for that particular class, a default constructor is implicitly created -- because it conforms to the rules I listed in this answer (and also in the link) – xaxxon Oct 06 '16 at 07:06
  • So when we declare Point point; It calls the default constructor which is Point(). And eventhough the constructor that we specify needs 2 arguments, but it is okay because both arguments have default values , which mean that I can call Point() just fine. Is that right? – mon Oct 06 '16 at 07:21
  • Point(int x = 0, int y = 0) is a default constructor. Any constructor which can be called with no parameters is a default constructor. – xaxxon Oct 06 '16 at 07:22
  • That's exactly what I meant. thanks for reconfirming. – mon Oct 06 '16 at 07:25
  • One more thing. Why Author does not have a default constructor? Which rule does it break? cause what I understood from reading is that even if I specify myown constructor, it will stil have implicitly declared constructor. – mon Oct 06 '16 at 07:38
  • 1
    I updated the answer -- if there are ANY user-provided constructors, a default constructor will not be implicitly created. However, you can force it by saying Author() = default; Spend some time and read that link. All the information is there. It's quite difficult to summarize any better. https://godbolt.org/g/SZA6SK – xaxxon Oct 06 '16 at 07:41
1

Implicit default constructors are not created for all objects.

The main rule is that when an object has no constructors of any kind, it gets assign an implicit default constructor.

I won't go over all the specific rules dictating when they get created, you're better off reading them from here.

As for your question 1 on the error message:

I tried to declare the object author inside the constructor instead of initializer list. It gave me error.

You don't show the code that produced the error, so I will assume it is like below - correct me if I'm wrong.

// sample A - Bad code, wont compile
class Author { };
class Book
{
public:
    Book(int x, Author y): n(1) {
        a(y);  //-this line does NOT compile. 
               // initialization of a must be in the initializer list,
               // between :  and {
    }
private:
    Author a;
    int n;
};

The reason the above does not compile is because it is a language rule that nested objects declared by value must be initialized in one of these 2 ways: - within the initializer list - implicitly, by letting the compiler call the default constructor - which will work if the object has one.

Finally, on your question 2, yes, that sample declaration of Point does invoke the default constructor, if the class has one. Again, refer to language reference to clarify on when the default constructor exists or not.

alex gimenez
  • 163
  • 11