Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to define struct only to be used as private member variable?

Tags:

c++

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;
};
like image 738
schumacher574 Avatar asked Aug 24 '16 17:08

schumacher574


People also ask

Can struct have private members?

Yes structures can have private members, you just need to use the access specifier for the same. struct Mystruct { private: m_data; }; Only difference between structure and class are: access specifier defaults to private for class and public for struct.

Can struct have private members in C?

Structure with private members in C++ As we know that by default, structures members are public by nature and they can be accessed anywhere using structure variable name. Sometimes a question arose "Can a structure has private members?" The answer is "Yes!

Can struct have public and private members?

A struct can indeed have public and private sections, member functions as well as member variables, and special functions such as constructors, destructors and operators.


2 Answers

For the option 2 to compile, _bar should be a pointer. Option 3 is best, since it doesn't pollute namespace.

like image 184
SergeyA Avatar answered Nov 16 '22 01:11

SergeyA


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<()) {}
like image 21
πάντα ῥεῖ Avatar answered Nov 16 '22 00:11

πάντα ῥεῖ