1

Sorry if this has been asked before, I can't seem to find anything. I'm not sure how to search for this.

I have something like this:

class A {
    private:
        int x;
        int y;
    public:
        A(int, int);
}

class B {
    private:
        A a(3, 4); // Doesn't compile because of this line
    public:
        B();
}

The only way I could think to solve this was making a a pointer to A and then do a = new A(3, 4); inside B's constructor. But I don't want a to be a pointer.

What's the correct way to solve this?

rfgamaral
  • 16,546
  • 57
  • 163
  • 275
  • Are all your defined types simple POD-like integral types? If so you could create them as non-type template parameters. eg. `A<3, 4> a;`. There are constrains to this approach though, one being those init values must be known at compile-time. – greatwolf Mar 14 '11 at 01:41

3 Answers3

2
class B {
    private:
        A a;
    public:
        B() : a(3,4) {}
};

In a wider sense, the solution is to learn C++ by reading a book about it. Yes, that's snarky, but the point of tutorials is that they introduce concepts in a sensible order, and when they tell you about data members they will simultaneously tell you how to initialize them.

Community
  • 1
  • 1
Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
2

You tag B's constructor with a "member initialization list". Instead of:

B::B() {
    ...
}

You do this:

B::B() : a(3, 4) {
    ...
}

Or if the constructor is defined in the header:

class B {
    private:
        A a;
    public:
        B() : a(3, 4) {
            ...
        }
};
Jonathan Grynspan
  • 43,286
  • 8
  • 74
  • 104
  • Isn't there any other way? What if I had dozens of variables to initialize? The code would look really weird. – rfgamaral Mar 14 '11 at 00:53
  • 2
    @Nazgulled: C++ does look weird, if you aren't familiar with it. It's not actually a problem until you have dozens of data members *and* more than one constructor. – Steve Jessop Mar 14 '11 at 00:55
  • 1
    @Nazgulled: C++ looks weird. That's part of the language. *Get over it.* That said, if you really hate the syntax, and `class A` has a default constructor, it will be used automatically; you can then assign a new value to `a` (`a = A(3, 4);`) in the constructor, but that's inefficient. Better to use the initialization list where possible as it can be better-optimized and produce smaller/faster code. – Jonathan Grynspan Mar 14 '11 at 00:56
  • Can I assume that that would be the same as declaring a `setVals` method to be used in `B`'s constructor as `a.setVals(3,4);`? Which is also inefficient? – rfgamaral Mar 14 '11 at 01:06
  • That plus the cost of actually replacing the contents of `a` with the contents of the temporary instance of `A`. If you haven't defined an assignment operator for `A`, then that's essentially a call to `memcpy()`--if you have, it's the cost of that method. The total cost of doing `a = A(3, 4)` will thus vary based on the actual type of `class A`. *Just get over your distaste of the syntax and use the initialization list. It will do exactly what you need and is the proper way to initialize fields in C++.* – Jonathan Grynspan Mar 14 '11 at 01:09
  • I was converting my current code to use classes instead, so another solution is to forget that idea for now. :P – rfgamaral Mar 14 '11 at 01:12
0

If what you want is for B.a to be initialized with the arguments 3 and 4, then you do that in B's constructor, e.g.,

class B {
    private:
        A a;
    public:
        B(): a(3, 4) {}
}
dfan
  • 5,714
  • 1
  • 31
  • 27