2

I would like some children (inheriting classes) to not see certain work functions that are in the Parent class. I understand that making these private would mean that the children cannot use these functions but the thing is that they would see them. I am trying to avoid the issue of having a bunch of "junk" show up in auto-complete.

With the above in mind, I have come up with an idea. Code below. The thing is that I am not entirely sure what the nature of secretFunc is. Is this a global function or does it belong to the Parent class in some way? It is not declared in the header, it is just defined in the cpp. The idea is that I could have some work functions like this in the Parent and then these would be hidden from the Child class. Is a more elite way to do this? Even if there is, I would still like to understand the nature of secretFunc.

#ifndef PARENT_H
#define PARENT_H

class Parent
{
public:
    Parent();
    ~Parent();

private:
    void privateFunc();
protected:
    void protectedFunc();
public:
    void publicFunc();

};

#endif

#include "Parent.h"

//What is the nature of this function???
void secretFunc()
{
}

UnitTest::UnitTest()
{
}

UnitTest::~UnitTest()
{
}

void UnitTest::privateFunc()
{
}

void UnitTest::protectedFunc()
{
}

void UnitTest::publicFunc()
{
}

#ifndef CHILD_H
#define CHILD_H

#include "Parent.h"

class Child : public Parent
{
public:
    Child();
    ~Child();
};

#endif

#include "Child.h"

UnitTest::Child()
{
}

UnitTest::~Child()
{
}

//Auto complete can see private Parent functions!
//Of course, child can't use them, but it can see them.
//I wish to hide these private functions from child.

//Auto complete can see and can also use protected Parent funcitons.
//As should be...

//Auto complete can see and can also use public Parent funcitons.
//As should be...

//secetFunc should be invisible.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
user440297
  • 1,181
  • 4
  • 23
  • 33
  • What IDE are you using wrt to AutoComplete? – sampson-chen Nov 22 '12 at 16:12
  • Qt Creator, Eclipse, Visual Studio. Scheme should work with all three. I mostly use Qt Creator though. – user440297 Nov 22 '12 at 16:14
  • You could use the [pimpl idiom](http://herbsutter.com/2011/11/04/gotw-100-compilation-firewalls/) to hide all private code in an implementation class. – juanchopanza Nov 22 '12 at 16:18
  • @juanchopanza I don't think he needs pimpl for this very purpose, he could just as well use an "impl" idiom (that is, no need for a pointer and dynamic allocation). – enobayram Nov 22 '12 at 16:54

4 Answers4

3

What you get with secretFunc() is essentially the opposite of what you get with privateFunc(). That is:

  • privateFunc() is visible but not accessible (nothing but other Parent methods can call it).
  • secretFunc() is not visible, but is accessible.

To elaborate, a free function defined like secretFunc() is in the global namespace, even though there is no declaration available in the header file. So code in any other file that is linked with Parent.cpp would be able to call secretFunc() by writing their own declaration, so long as it is correct.

That is, Child.cpp could contain

void secretFunc();

At the top, which makes the function visible, and then anything in Child.cpp could call secretFunc().

If all you're trying to do is make the function invisible to autocomplete, then this may not be a concern. But you can achieve both invisibility and inaccessibility at once. What you need to do is remove secretFunc from the global namespace. You can do that by enclosing it in an anonymous namespace.

So in Parent.cpp you write:

namespace {
  void secretFunc() {
     // ...
  }
}

This makes the function both invisible and inaccessible to anything outside the Parent.cpp file. If Child.cpp were to make its own declaration (as described above), the linker would produce an error because it would not be able to find a function with the secretFunc name in the global namespace.

Note that this is different from a private method, in to ways:

  • The accessibility is limited to things in the Parent.cpp file, not the Parent class.
  • Because it is not a class member of Parent, it has no special access into Parent objects (and doesn't have a this pointer).

One final thing. Using the static keyword instead of enclosing the function in an anonymous namespace has the same effect, but this is a C-ism. Using the anonymous namespace is the idiomatic C++ way to do it.

Tyler McHenry
  • 74,820
  • 18
  • 121
  • 166
  • Thanks for this excellent post and seemingly brilliant scheme. I take it that assigning an anonymous namespace is the same as removing it from any namespace, so how is it that the cpp file can still see it? I'm just curious. Also, do you think that this scheme will be something I can depend on not being broken in future compiler updates? – user440297 Nov 22 '12 at 17:07
  • *Using the anonymous namespace is the idiomatic C++ way to do it.* => actually... C++11 reinstates `static` (no longer "deprecated") because it's so damn easier to type. – Matthieu M. Nov 22 '12 at 17:41
  • @user440297 This is standard C++, so it will definitely not be broken in future updates. Anonymous namespace is not exactly the same as removing it from _any_ namespace, it's actually putting it into the "file local" namespace instead of the "global" namespace (global being the default). So anything in the file can access things in the file-local namespace. – Tyler McHenry Nov 22 '12 at 17:42
  • Thank you. I didn't know there was a "file local" namespace. It seems to make sense now. – user440297 Nov 22 '12 at 18:22
1

The secretFunc is a stand-alone function which can be called by anybody who sees it or its declaration. It is different from class methods in that it has no access to members of the class instance which calls it.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Igor
  • 15,833
  • 1
  • 27
  • 32
1

For your question about hiding private member functions from auto complete, it depends on your IDE, but if you're using Visual Studio it looks like it isn't possible. If you're using Qt Creator, it also looks like it isn't possible. I am unsure of Eclipse, but I suspect it's not possible as well. When I say "not possible," I mean not possible without changing your code. The pimpl idiom can be used to hide private members as well as external dependencies. Of course, your private pimpl will still be visible by auto complete, but it would be an incomplete pointer type, so it's not much use to the user, and it's only one member.

For your question about secretFunc, if you make secretFunc static, then only Parent.cpp will be able to see and use it. As it currently is, any other source file can say extern void secretFunc(); and then start using secretFunc.

If you give it the static modifier (static void secretFunc()), then it can only be seen by the source file its in. The linker won't expose it to other translation units.

Community
  • 1
  • 1
Cornstalks
  • 37,137
  • 18
  • 79
  • 144
  • Why would adding the static modifier limit a functions scope? I thought that static modifier for a function merely makes function members that would have gone on the stack go in the data section instead so that state is retained accross calls? I don't understand how the scope (visibility) would be affected by this. Is this some sort of copiler dependant special behaviour? – user440297 Nov 22 '12 at 16:46
  • @user440297: It's not a compiler dependent behavior; it's part of the C/C++ language specifications. Note that what I said applies to *free functions* (which is what `secretFunc` is), not *member functions*. If you put `static` on a global function or variable, it is not accessible to other translation units. If you put `static` on member functions/variables, that's completely different, and just makes it so you no longer need a class instance to use it. If you put `static` on a local variable, the variable has static storage and duration. `static` has different effects for how it's used. – Cornstalks Nov 22 '12 at 16:59
  • Thank you for your post. I chose the other answer because it described both this scheme and the anonymous namespace scheme plus it explained associated ideas clearly. I thought your answer was also good. I upvoted your answer. – user440297 Nov 22 '12 at 18:24
  • @user440297: Thanks. I actually wasn't aware of the affects of an anonymous namespace, so I'm glad Tyler McHenry shared that. – Cornstalks Nov 22 '12 at 18:37
0

You can have private virtual functions, and you can override (but not call) them in derived classes. This language feature is, as they say, widely known in narrow circles. People are using it in production code.

So it would seem that hiding private members from IDEs is counterproductive.

In VS, you can hide any member from IntelliSense using a little preprocessor trick:

#ifndef __INTELLISENSE__    
void ThisShouldNotBeSeen() {}
#endif

but this will hide it from IntelliSense everywhere, not just in derived classes. This is inconvenient when developing the parent class itself, as you get lots of spurious IntelliSense errors and red underlines. It could be useful to add this macro to header files you release.

I'm not sure about other IDEs.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243