deleted default constructor headache - c++

My c++ book says this (lippman, c++ primer, fifth ed., p. 508):
The synthesized default constructor is defined as deleted if the class ... has a const member whose type does not explicitly define a default constructor and that member does not have an in-class initializer. (emphesis mine)
Why then does this code produce an error?
class Foo {
Foo() { }
};
class Bar {
private:
const Foo foo;
};
int main() {
Bar f; //error: call to implicitly-deleted default constructor of 'Bar'
return 0;
}
The rule above seems to indicate that it should not be an error, because Foo does explicitly define a default constructor. Any ideas?

To fix your error. You need to make Foo::Foo() public.
class Foo
{
public:
Foo() { }
};
Otherwise I do believe it is private.
Is this what your looking for?

The default constructor is omitted when a a class construction isn't trivial.
That in general means that either there is an explicit constructor that receives parameters (and then you can't assume that it can be constructed without those parameters)
Or if one of the members or base classes need to be initiated in construction (They themselves don't have a trivial constructor)

I think that this should work
class Foo {
public:
Foo() { }
};
class Bar {
public:
Bar() : foo() {}
private:
const Foo foo;
};

Related

C++ How to initialize members with hidden default constructors?

I have a class with a hidden default constructor to force the use of a constructor taking parameters. Another class is using 2 instances of the class:
typedef struct { ... } BAZ;
class Foo {
private:
Foo(void) {}
public:
Foo(BAZ a) { ... }
};
class Bar {
private:
Foo foo1;
Foo foo2;
Bar(void) {}
public:
Bar(BAZ a, BAZ b) : foo1(a), foo2(b) { ... }
};
The most obvious is that the declaration of the variables foo1 and foo2 will call the default Foo constructor, but since it is private it can't and will give a compiler error.
Is there a way to prevent it from trying the default Foo constructor and just wait for the Bar constructor to initialise them instead?
I want to avoid the use of the new keyword (which would solve the whole problem).
EDIT:
It seems like people have a hard time to understand the question and dilemma. I will try to explain:
I want to force the use of a Foo(BAZ) constructor meaning that any attempt to use the Foo(void) constructor will generate an error.
To hide the default constructor it is declared as a private member. If someone try to use the default constructor Foo() it will give an intentional error.
To not declare the default constructor and only declare Foo(BAZ) is not preventing the compiler to create a public default constructor. It gives no error if I declare it Foo(). So far it works fine and as intended.
The second class Bar have two instances of Foo but when Bar is instanced these Foo members will be called with the default (hidden) constructor and generate an error. Then in the Bar constructor, these two instances will be initialized with the correct public constructor Bar(BAZ a, BAZ b) : foo1(a), foo2(b). This is what I want.
Is there a way to prevent it from calling Foo default constructor when Bar is initialized, so the Bar constructor can use the correct Foo constructor?
The new solution works because the default constructor is never called:
BAZ a = {...}
Foo *foo1 = new Foo(a);
I hope this makes it more clear.
EDIT2: SOLVED
The error wasn't in the hidden Foo constructor, it was the hidden Bar constructor trying to use the hidden default Foo constructors.
Bar(void) : Foo(BAZ{}), Foo(BAZ{}) {}
Solved it.
EDIT3:
The real problem seems to have been in the development tool. After restart and manually clearing the cache it worked as the C++14 standard intended.
the declaration of the variables foo1 and foo2 will call the default
Foo constructor
No. Declaring these member variables only says that they are members. It doesn't say anything about how they will be constructed. That's the job of the constructor(s) of the class that uses them.
Bar(BAZ a, BAZ b) : foo1(a), foo2(b) { ... }
Fine so far: this constructor constructs the foo1 and foo2 members using the constructor Foo(Baz).
Bar(void) {}
This is the problem: it attempts to construct the foo1 and foo2 members with the default constructor for Foo. Since that constructor is not accessible (that's the correct term; it is not hidden), you get an error. There are at least three solutions:
1:
Bar() : foo1(Baz()), foo2(Baz()) {}
This uses the constructor that takes Baz.
2:
Bar() = delete;
This makes the default constructor for Bar not exist, so it doesn't try to use the default constructor for Foo.
3:
Just don't do it. If you don't write a default constructor but you do write another one, the compiler won't generate a default constructor.
Don't hide constructors. Don't declare them in the first place.
typedef struct { ... } BAZ;
class Foo {
public:
Foo(BAZ a) { ... }
};
class Bar {
private:
Foo foo1;
Foo foo2;
public:
Bar(BAZ a, BAZ b) : foo1(a), foo2(b) { ... }
};

My constructor specifies at least one value for construction, and yet it can be default constructed

Take the following class:
class Foo{
public:
Foo(std::string bar_, int baz_ = 7)
:bar(bar_)
,baz(baz_)
{}
private:
std::string bar;
int baz;
};
Since Foo(std::string bar_, int baz_ = 7); is my only constructor, the compiler shouldn't implement a default constructor for me right? I would think that the only two ways I could construct this class are:
Foo foo("foo");
//or
Foo foo("foo",0);
//plus copy constructor and overloaded assignment operator.
Yet, why is this possible?
int main(){
Foo foo();
}
I don't understand how I can default construct a class when the only public constructor requires a value for its first parameter. Making the default constructor private or trying to C++11 delete it, makes no difference. How is this happening?
http://ideone.com/CL7IZo
Because Foo foo(); is a forward declaration of a function which returns a Foo and takes no arguments. Use Foo foo; instead and you will get your error.

Use of this in initializer list

Suppose I have a class Baz that inherits from classes Foo and Bar, in that order. The constructor for class Bar takes a pointer to a Foo object. What I would like to do is to pass this as the Foo object to the Bar constructor:
Baz () : Foo(), Bar(this) {}
A working example:
#include <iostream>
class Bar;
class Foo {
public:
virtual ~Foo() {}
virtual void parse_bar (Bar&) const = 0;
};
class Bar {
private:
const Foo * parser;
public:
Bar (const Foo * parser_in) : parser(parser_in) {}
virtual ~Bar() {}
void parse_self () { parser->parse_bar (*this); }
};
class Baz : public Foo, public Bar {
public:
Baz () : Foo(), Bar(this) {}
virtual void parse_bar (Bar &) const { std::cout << "Hello World\n"; }
};
int main () {
Baz baz;
baz.parse_self();
}
This happens to work on my computer, with my compilers (tested with a couple of them). However section 9.3.2 of the 2003 standard makes me a bit uneasy that I might just be getting lucky, that using this this way is undefined behavior. Strictly speaking, the initializer list is outside the body of the constructor. Here's the relevant text, emphasis mine:
9.3.2 The this pointer
In the body of a nonstatic member function, the keyword this is a non-lvalue expression whose value is the address of the object for which the function is called.
So is my usage legal and well-defined, or is it undefined behavior?
There are two points that have to be noted in this case.
Firstly, in the constructor initializer list this pointer refers to a non-constructed (or not-fully-constructed) object. It is OK to access such pointer, but the object it refers to can only be used in limited ways. See 12.7 in the language specification.
Secondly, in your specific example what you are actually doing is converting this pointer to Foo * type before attempting any access. This is completely safe since by that moment the Foo subobject is fully constructed. (I assume that, whatever access will follow, if any, will be restricted only to the fully constructed Foo subobject).
The only concern is this case is whether it is legal to convert this to Foo * type, i.e. whether the conversion process itself should succeed. The answer is: yes, in case of ordinary (non-virtual) inheritance such conversion is perfectly legal and safe (again, explicitly allowed in 12.7)
It is fine. The C++ standard actually clarifies the use of this pointers in initializer lists:
12.6.2 Initializing bases and members [class.base.init]
Paragraph 7: Names in the expression-list of a mem-initializer are evaluated in the scope of the constructor for which the mem-initializer is specified. [Example:
class X {
int a;
int b;
int i;
int j;
public:
const int& r;
X(int i): r(a), b(i), i(i), j(this->i) {}
};
initializes X::r to refer to X::a, initializes X::b with the
value of the constructor parameter i, initializes X::i with the
value of the constructor parameter i, and initializes X::j with
the value of X::i; this takes place each time an object of class X
is created. ] [Note: because the mem-initializer are evaluated in
the scope of the constructor, the this pointer can be used in the
expression-list of a mem-initializer to refer to the object being
initialized. ]
The type of the this pointer in the initializer of Baz is in fact of type Baz. Of course, you have to be mindful of the fact that not all of the members may have been initialized. Many, if not all, compilers set at their highest warning levels (which you really should be doing anyway) will warn about you passing a this pointer to the base class.
However, it looks like you're making it more complicated that it needs to be. Why not just put the virtual function parse_bar() in the Bar class, and forget about the Foo class?
#include <iostream>
class Bar
{
public:
Bar() {}
virtual ~Bar() {}
void parse_self () { parse_bar(); }
private: // Template method pattern
virtual void parse_bar() const = 0;
};
class Baz : public Bar
{
public:
Baz () {}
private: // Yes, this does override the private `parse_bar()` member!
virtual void parse_bar() const { std::cout << "Hello World\n"; }
};
int main ()
{
Baz baz;
baz.parse_self();
}
This does essentially the same function but with less code.

const reference must be initialized in constructor base/member initializer list

I am trying to block access to the default constructor of a class I am writing. The constructor I want others to use requires a const reference to another object. I have made the default constructor private to prevent others from using it. I am getting a compiler error for the default constructor because the const reference member variable is not initialized properly. What can I do to make this compile?
class CFoo
{
public:
CFoo();
~CFoo();
};
class CBar
{
public:
CBar(const CFoo& foo) : fooReference(foo)
{
}
~CBar();
private:
const CFoo& fooReference;
CBar() // I am getting a compiler error because I don't know what to do with fooReference here...
{
}
};
don`t declare default constructor.
It is not available anyway (automatically that it's) if you declare your own constructor.
class CBar
{
public:
CBar(const CFoo& foo) : fooReference(foo)
{
}
private:
const CFoo& fooReference;
};
fairly comprehensive explanation of constructors can be found here:
http://www.parashift.com/c++-faq-lite/ctors.html
The easiest way to create the default constructor you don't wanna use (that is the case with your constructor, is that right?) is just not defining it, that is:
class CBar
{
public:
CBar(const CFoo& foo) : fooReference(foo)
{
}
~CBar();
private:
const CFoo& fooReference;
CBar();
};
In this case, it may be a little superfluous, because the compiler will not create a default constructor for a class with a reference member, but it's better to put it there in case you delete the reference member.

Private variable needs to be initialized only in constructor. How?

I have a class called Foo with a constructor that needs arguments, and a other class Bar with a Foo private variable
class Foo
{
public:
Foo(string);
}
class Bar
{
public:
Bar() { this->foo = Foo("test") }
private:
Foo foo;
}
However, when I try to compile this, I get a compile error that there is no Foo::Foo() constructor. It looks like the private variable foo in class Bar gets initialized before getting a value assigned in the constructor.
How can I have a private foo variable that waits to gets initialized in my constructor?
You need to use an initializer list. If you don't, your code will call the default constructor for that object.
Bar::Bar() : foo("test") {
// stuff
}
Use an initializer list:
Bar() : foo("test") {}
BTW, in C++ reasons to use this-> are rare (and often indicate other problems).