2

I'm not coding much in C++, so please forgive me if this is trivial.

My class "Foo" looks somewhat like this:

class Foo {
    public: Foo(int n) { }
};

Another class "Bar" is now supposed to have a class member of type "Foo".

class Bar {
    private: Foo f;
};

This obviously fails, because there is no constructor for "Foo" that does not require any arguments. However, stuff like Foo f(1); fails, too.

Is there any way to solve this problem? Or am I supposed to use a pointer here?

Niko
  • 26,516
  • 9
  • 93
  • 110

4 Answers4

6
class Bar {
public:
    Bar():f(0) { }
    explicit Bar(int n):f(n) { }
    private: Foo f;
};

write your own c-tors, using initializer-list, or write c-tor without parameters in Foo, or use pointer, or in C++11 you can write

class Bar {
public:
    private: Foo f = Foo(1);
};
ForEveR
  • 55,233
  • 2
  • 119
  • 133
4

This can be handled in 2 different way.

(1) Provide appropriate argument constructor for class Foo

You can either introduce a no argument constructor Foo() or edit the current one accepting default argument, i.e. Foo(int n = 0)

(2) Call constructor of class Foo inside the Bar with appropriate arugment

e.g.

class Bar {
...
  Bar() : f(0) {}  // (a) pass the argument explicitly 
  Bar(int n) : f(n) {} // (b) receive argument inside Bar()
};
iammilind
  • 68,093
  • 33
  • 169
  • 336
  • In general, one-argument constructors should be made `explicit` to forbid for unintended conversions, like in your example from `int` to `Bar`. I would use `explicit Bar(int n=0) : Foo(n) {}` in this case. – Sebastian Mach Aug 13 '12 at 09:04
  • @phresnel, I believe that is case to case. Some ppl want to have those conversion intended and some ppl don't want them. I will leave it upto the coder. – iammilind Aug 13 '12 at 09:06
  • Is there any difference between `Bar() : Foo(0)` and `Bar() : f(0)`? – Niko Aug 13 '12 at 09:08
  • 1
    `Foo` is not a base class, so you cannot call it's constructor that way. You have to say which member you want to initialize. – Pawel Zubrycki Aug 13 '12 at 09:13
  • @Niko: yes, there is. `Foo(0)` calls c-tor of base class `Foo`, so it is wrong here. `f(0)` calls c-tor of `f` class member. – Pawel Zubrycki Aug 13 '12 at 09:15
  • @iammilind: I wrote "in the general case", implying that sometimes you _want_ that behaviour, but personally, outside of math-centric libraries, I almost never see them, and even inside math-centric libs, I only seldomly see them. Actually, I most often see it where not appropriate and where the author just wasn't aware of the reach of the consequences of making it implicit (see also http://stackoverflow.com/a/4121438/76722). On another note: I realise you either forgot to derive from `Foo`, or have an error and it should be `Bar() : f(0)` instead. – Sebastian Mach Aug 13 '12 at 09:24
0

You may have a default constructor for Foo or use pointer of Foo in class Bar and set an object later.

Lwin Htoo Ko
  • 2,326
  • 4
  • 26
  • 38
0

I guess if your Foo needs an argument to construct there are two possibilities:
- Either your Bar will use a static number for constructing his own Foo (all Bar will have the same n in Foo)
- Either your Bar's will have different numbers in their member Foo. You can then pass a number to Bar constructor as follows:

class Bar {
    Bar(int n) : Foo(n) { ... } ;
    }
maxbc
  • 949
  • 1
  • 8
  • 18