Reputation: 1129
Take the following header file example, where Bar is a struct:
class Foo
{
...
private:
Bar _bar;
};
I only want Bar
to be accessible as a private member variable for Foo
. What is the proper way to declare and define Bar
?
Option 1: define in header?
I'd like to avoid this, as I don't want Bar
to be usable outside the Foo
class scope.
struct Bar
{
int a;
int b;
...
};
class Foo
{
...
private:
Bar _bar;
};
Option 2: forward declare in header, define in cpp?
Not sure if this is legal, as how will the compiler know the size of Foo
strictly from the header if Bar
's definition isn't directly available? Also, will this hide Bar
from other files that include the header?
header:
struct Bar;
class Foo
{
...
private:
Bar _bar;
};
implementation file:
struct Bar
{
int a;
int b;
...
};
Option 3: declare within class
Maybe the best option to limit scope, but potentially messy?
class Foo
{
...
private:
struct Bar
{
int a;
int b;
...
};
Bar _bar;
};
Upvotes: 19
Views: 9475
Reputation: 1
Option 3: declare within class
Maybe the best option to limit scope
Of course, that's the best way to limit scope and doesn't pollute the namespace. Go for option 3.
but potentially messy?
I didn't get your concerns (you may wanted to elaborate that in your question), there's nothing messy with that at all.
Note: Whenever needed to make a roundtrip from clients with it, they can use the auto
keyword to refer to Bar
variables.
Another option as mentioned by R.Sahu, is to use the Pimpl Idiom:
struct FooData;
class Foo {
...
private:
std::unique_ptr<FooData> data_; // Note I not prefer to use leading underscores
public:
Foo();
};
And in Foo
's translation unit:
namespace {
struct FooData;
{
int a;
int b;
...
};
}
Foo::Foo() : data_(std::make_unique<FooData<()) {}
Upvotes: 7
Reputation: 11769
Option 1: define in header?
I'd like to avoid this, as I don't want Bar to be usable outside the Foo class scope.
With option one, you just answered your own question.
Option 2: forward declare in header, define in cpp
Same problem here as option 1(scope visibility ), but only advantage is Bar's implementation won't be visible to other .cpp
files.
Option 3: declare within class
Option 3 is the best, since it fulfills the purpose you ask for, and only that. In addition, with that Bar
is available to the whole class. Also, nesting the class prevents unnecessary clutter in your code, as nothing except Foo
can access Bar
. And it definitely does NOT seem messy, and plus, you could declare just the struct like this:
class Foo
{
private:
struct Bar {int a, int b};
//.....
};
For a small class, and that seems ok since it is a 1-liner. A disadvantage would be forward-declaring the class, not possible, as seen in this answer: https://stackoverflow.com/a/951245/6525260.
Upvotes: 4
Reputation: 62553
For the option 2 to compile, _bar
should be a pointer. Option 3 is best, since it doesn't pollute namespace.
Upvotes: 12