DEV Community

齊藤敦志
齊藤敦志

Posted on • Updated on

Can I hide the type?

Private member is not accessible from outer the class. Private member is inner only unless provide indirect method by pointer or reference.

And I can specify private for type.

For example,

#include <iostream>

class foo {
private:
  class bar {};
public:
  static bar make_bar(void) {
    return bar();
  }
  static void print_bar(bar) {
    std::cout << "bar" << std::endl;
  }
};
Enter fullscreen mode Exit fullscreen mode

I hope hide foo::bar. I do not want you make objects of foo::bar type.

In C++11 and later, you can use private types with auto or decltype.

int main(void) {
  foo::make_bar(); // OK
  foo::print_bar(foo::make_bar()); // OK
  foo::bar x = foo::make_bar();    // Error : foo::bar is private
  auto x = foo::make_bar();        // OK : You can use `auto` in C++11 and later
  decltype(foo::make_bar()) y = foo::make_bar(); // OK : You can use `decltype` in C++11 and later

  return 0;
}
Enter fullscreen mode Exit fullscreen mode

Is there way to hide the type?

Top comments (2)

Collapse
 
jakebman profile image
jakebman • Edited

Are you trying to make client code unable to store a variable of foo::bar?

The intent being that you can foo::print_bar(foo::make_bar()); but not

/*variable*/ x = foo::make_bar();
foo::print_bar(x);

It's possible to (forward-)declare a type without fully specifying its layout. If you do that, like in the (P)rivate (Impl)ementation pattern, you prevent callers from another compilation unit from being able to create instances of your class.

However, if you do that, foo::make_bar() must return - and foo::print_bar() must accept - a pointer to foo::bar, not an actual foo::bar instance itself. And callers will still be able to store the result from make_bar() into a variable.

If that does not solve your situation, I would look into the various ways that class objects can be created, initialized, and mutated and start removing them from foo::bar until the problem is solved to your satisfaction. For instance, if foo::bar can't be assigned from another foo::bar, you'll prevent x = foo::make_bar(); but not for instance x{foo::make_bar()}; which is at least a good start.

This is a fun puzzle, but I'm wary of going deeper into a solution if this is going to be used in production code. I'd like to hear more about why this restriction is necessary before trying too hard to implement it, because I am wary of The XY Problem and want to solve the underlying problem, not the surface problem.

Collapse
 
saitoatsushi profile image
齊藤敦志

I haven't thought about problem in a concrete situation.

This entry is an episode that I found that what was possible in C++03 became impossible in C++11.