VS2012 - Class Interface Design: Private Member Funcs Positioning / Hiding - c++

In VS, when you type "class." you are presented with a list of functions you can call. Having to look through a list of 15-20 functions, half or more of which being members is not nice.
I'm extremely interested in finding a system that will hide private member functions or move them to the end of the list, so the user doesn't have to scroll through a list of locked functions.
I have four design types:
1) Namespace method hiding
2) Class based method hiding
3) pimpl version
4) _ prefix
Here is the code for clarity:
#pragma once
#include <memory>
using namespace std; // ignore the fact this is global here
struct Hide_Test_Data
{
int value;
};
namespace Hide_Test_Private_Member_Ns
{
void private_function(Hide_Test_Data& data) {}
};
class Hide_Test_Methods
{
public:
Hide_Test_Methods() {}
void private_function(Hide_Test_Data& data) {}
};
class Hide_Test_Methods_Alt
{
public:
Hide_Test_Methods_Alt() {}
void private_function() {}
private:
Hide_Test_Data htd_;
};
class Hide_Test
{
public:
Hide_Test() {}
void public_function()
{
_private_function(); // member function prefixed with _
Hide_Test_Private_Member_Ns::private_function(htd_); // namespace version
htm_.private_function(htd_); // subclass version (no private data)
pimpl->private_function(); // pimpl version (with private data)
}
private:
Hide_Test_Data htd_; // class to hold data
Hide_Test_Methods htm_; // class to hold methods
void _private_function() {}; // _ prefixed member function
unique_ptr<Hide_Test_Methods_Alt> pimpl;
};
Note:
The unique_ptr Hide_Test_Methods_Alt version has member data which the standard one doesn't. Both could be implemented in either way.
The _ prefix doesn't hide the member data, but it does move it to the end of the list. This has the advantage of allowing user to see the private functions if they are interested. My main goal is not to hide the private member functions, just to move them out of the way.
Prefixing data with _ 'should' be safe out of global scope according to the standard as long as it is followed with a lowercase letter.
Which of these designs would be more acceptable in general? I imagine I could work with all four of these design types comfortably, but I would rather hear some input on some of the pros and cons I may not have thought of.
Pimpl uses a pointer to ease copying the member data. In the cases where I don't need to copy the member data, is just using a class better or worse?
I have done some research and found a few related threads in this forum:
Hiding private data members? (C++) - this one points out the pimpl idiom (which I added to my examples above).
How to hide private members of a Class? - talks about VS intellisense not hiding private members
Why does Visual Studio's intellisense show private members and functions? - gives an #ifdef solution that I don't really like the idea of.
I think this question is different enough from the others presented to be worthy posting. Thanks as always.

Generally a pimpl pattern is applied when you want to be able to change implementations at link time and as such must be a pointer
Here you don't want the overhead, so you could consider an inner class and an instance of that class as opposed to a pointer:
class fewfunctions
{
class manyfunctions
{
public:
int a1() { return 0; }
int a2() { return 0; }
int a3() { return 0; }
int a4() { return 0; }
// ... many more
};
public:
int b() { return a.a1() + a.a2() + a.a3() +a.a4(); }
private:
manyfunctions a;
};
Only b will show up as a function (a shows up as locked)

Related

using namespaces instead of singletons

Recently I posted a question on SO regarding usage of a class which carried a bit of separate functionality that it should've, ideally. I was recommended to learn about singleton pattern so that only one instance is created of the class and it manages the set of operations revolving around the data it encapsulates. You can see the question here - using Static Container for base and derived classes .
Now consider this code -
#include <iostream>
#include <string>
#include <unordered_map>
class A{
std::string id;
public:
A(std::string _i): id(_i){}
virtual void doSomething(){std::cout << "DoSomethingBase\n";}
};
class B : public A{
std::string name;
public:
B(std::string _n):name(_n), A(_n){}
void doSomething(){std::cout << "DoSomethingDerived\n";}
};
namespace ListA{
namespace{
std::unordered_map<std::string, A*> list;
}
void init(){
list.clear();
}
void place(std::string _n, A* a){
list[_n] = a;
}
}
int main() {
ListA::init();
ListA::place("b1", new B("b1"));
ListA::place("a1", new A("a1"));
return 0;
}
Ignoring the fact that I'm still using raw pointers which are leaking memory if program doesn't terminates as it is, is this a good alternative to using global static variables, or a singleton?
With regard to previous question, I've reorganized class A(base class) and class B(derived classes) independent of a namespace that manages a list of these objects. So is this a good idea, or a totally bad practice? Are there any shortcomings for it?
A good singleton implementation I was suggested was as follows -
class EmployeeManager
{
public:
static EmployeeManager& getInstance()
{
static EmployeeManager instance; // Guaranteed to be destroyed.
// Instantiated on first use.
return instance;
}
private:
EmployeeManager() {};
std::unordered_map<std::string, Employee&> list;
public:
EmployeeManager(EmployeeManager const&) = delete;
void operator=(const&) = delete;
void place(const std::string &id, Employee &emp){
list[id] = emp;
}
};
class Employee
{
public:
virtual void doSomething() = 0;
};
class Writer : public Employee
{
private:
std::string name_;
public:
Writer(std::string name) : name_(name) {};
void doSomething() { };
};
Honestly I've never tried singleton pattern and I'm shying away to use it directly since I've no prior experience and I would rather first use it in my pet projects.
is this a good alternative to using global static variables, or a singleton?
no, because you might encounter another problem: static initialization order fiasco. There are ways to fix it - but with functions with static variables - which looks just like singletons.
... but why do you need a global variables (even in namespaces) or singletons? In you first example, it would be perfectly fine if instead of namespace ListA you had struct ListA - plus remove that namespace{. Then you have:
int main() {
ListA list;
list.init();
list.place("b1", new B("b1"));
list.place("a1", new A("a1"));
}
and it looks fine.
Then your singleton aproach, once again - no need for it - create variable of type EmployeeManager in your main function, if you need to use it in some other class, then pass it by reference or pointer.
I'm not sure if you know that already, but you need to remember that Singleton really is a global variable with lazy initialization.
Lazy initialization is a tool to fix a problem of having the object initialized always at the time when you really want to use it - be it for some real-program function, or initializing another, dependent object. This is done to delay initialization until the first moment when you use the object.
The static object is simply initialized at the moment when it first appears to need to be created - however when this moment really is, is undefined, at least in C++.
You can replace lazy initialization with the static initialization, but you must ensure somehow that the initialization happens in defined order.
Defining variables inside the namespace is nothing else than declaring the variables globally. Namespaces are open, rules inside the namespace are the same as outside the namespace, except the symbol resolution.
What you can do to enforce ordered initialization is to create one global variable with all dependent global objects inside, in the form of struct that will contain all them as fields (not static fields!). Note though that the exact order of initialization will be only ensured between objects being fields of that structure, not between them and any other global objects.
Your question can be answered without any line of code, as it was answered by a lot of people in the past. Singletons are bad because your code will depend on one class and its implementation. What you want though is to have independent units which don't know about the implementations of the interfaces they talk to. Propagation of values / reference should (in fact it must be done for large maintainable systems) via reference passing from containing object to its child, an observer / event system or an event / message bus. Many frameworks use at leat two of these approaches ... I highly recommend sticking to best practices.

Making subclasses that can call on each other's shared member variables

I'm new to C++ and I'm having trouble with this. So I'm trying to make classes that can call on each other's fields using a generic subclass.
Basically, I'm trying to make a game where there is a generic type and three types that have strengths/weaknesses against each other. I only really have experience in Java, and the translation to c++ for this kind of thing isn't clicking for me
Generic type splits into three types: type 1, type 2, type 3.
Generic type needs to be concrete
In the generic type there are fields attack, defense, hitpoints
types 1, 2, and 3 all inherit these fields.
I'm trying to make a virtual function in the generic class:
virtual void attack(Generic* g);
Problem is, when I try to make type_1.attack(generic) for example, I want to do g->hitpoints to get generic's hitpoints, but it just doesn't seem to work like that in C++.
Additionally, I know I must be doing something wrong, because type 1, 2 and 3 all include the generic type's header, but if I want to include those 3 headers in main.cpp, it'll give me an error for declaring generic 3 separate times.
How would I go about doing this?
Sorry this is a very specific question and it's a little bit vague. Please let me know if I need to clarify anything
Edit: Here is the basic setup of what I'm talking about
//in generic.h
class Generic {
protected:
int hitpoints;
int strength;
int defense;
public:
virtual void attack(Generic* g);
};
//type1.h
#include 'generic.h'
class Type1 : public Generic {
void attack (Generic* g);
};
//in type1.cpp
void Type1::attack(Generic*g) {
g->hitpoints = strength - g->defense;
}
An object can access its own protected members that are inherited from a base class. But an object cannot access another object's protected members. That is the difference between private vs protected - private members can only be accessed by the class that declares them, but protected members can be accessed by the declaring class and its descendants. Both are still private to outside code, though.
To do what you are attempting, hitpoints needs to be public.
type 1, 2 and 3 all include the generic type's header, but if I want to include those 3 headers in main.cpp, it'll give me an error for declaring generic 3 separate times.'
You need to make sure that the class is declared only once. This is usually done with guards in the .h file:
//generic.h
#ifndef GENERIC_H
#define GENERIC_H
//all declarations go here
#endif /* GENERIC_H */
When you type #include "generic.h", the C++ processor will basically just paste the contents of foo.h. Since you included it thrice (via the includes for classes Type1, Type2 and Type3, that each include generic.h), the class is delcared three times.
You should do something like this:
// generic.h
#pragma once
class Generic {
protected:
int hitpoints_;
int strength_;
int defense_;
void do_damage(Generic* g, int damage) { g->hitpoints_ -= damage; }
public:
virtual void attack(Generic* g) = 0;
int hitpoints() const { return hitpoints_; }
int strength() const { return strength_; }
int defense() const { return defense_; }
};
// type1.cpp
void Type1::attack(Generic* g) {
do_damage(g, strength_ - g->defense());
}
To avoid your second problem (a class defined multiple times), there is something called include guards (they guard you from including the same file several times). It works like this way:
// File: type1.h
// At the very beginning
#ifndef type1_h
#define type1_h
// Here come the rest of your file and, at the end:
#endif
This way, the contents of the file are only included once, because after that type1_h will be defined, so everything will be skipped. This may be the only use of #define that is universally accepted in C++.
As for your first problem, protected means that derived classes can read that member for themselves or objects of their own class, but nobody else. This includes that derived classes cannot read that member for objects belonging to another class, including the base class itself. I'm afraid you'll have to rethink your design.
The best that you can do is just changing the privacy of the protected members or, even better, provide public accessors and keep the data members private. public data members are seldom a good idea in classes (structs are a different thing):
class Generic {
private:
int hitpoints;
int strength;
int defense;
public:
virtual void attack(Generic* g);
void SetHitpoints(int hp) {hitpoints = hp;}
int GetDefense() {return defense;}
};
The meaning of protected for data members is subtly different from what you might expect. When you have a class A with a protected data member d and a class B that inherits from A (with public inheritance), then B's member functions can access d – but only on objects of type B, not on any object of type A. If that seems confusing, a code example will hopefully make it clearer:
class A {
protected:
int d;
};
class B : public A {
void fine(B& b) { b.d = 0; }
void wrong(A& a) { a.d = 0; }
};
int main() { }
As the names indicate, the assignment in functions fine is ok, but you'll get a compiler error for the one in wrong if you try to compile the code. The best way to deal with this is probably to make the data members private and write protected member functions that operate on them, as in abyss.7's answer.
For the double inclusion problem, use either include guards or #pragma once.

Initializing a friend's reference member to a class private member

I want to initialize a member (of reference type) in one object to point to a private member of another object (of a different type). I use friend to provide access to the private member. (Please bear with me for a bit, I explain further down why I need to do this.)
Below is a bare minimum version of the code I tried to get started with, and it obviously does not work. Now clearly, I am only trying to initialize the reference with this code Aries a(t.Leo);, but because this is done inside main(), it does not compile.
I went through a number of posts here and on the internet (on the topics of friend and reference), but could not figure out a way to solve it. How could I make this work, or what other approach could I try to bind the reference correctly?
class Aries;
class Taurus {
friend class Aries;
public:
void setLeo(int inLeo) {
Leo = inLeo;
}
private:
int Leo;
};
class Aries {
public:
Aries(const int& inCancer) : Cancer(inCancer) {}
private:
const int& Cancer;
};
int main() {
Taurus t;
Aries a(t.Leo); // Intention: initialize (bind) the Cancer member with t's Leo.
}
Note I know enough C++ to understand why the above practice is considered questionable or bad.
I am working on a research project in a hardware simulation environment, where the testbench is written in C++. The aim of the project is to display the class (private) members as a waveform. The only reliable way of doing this is to make the "waveform maker" class as a friend of the testbench objects, and then have it "stalk" the private members (by creating a reference as above). The other alternative of providing getter methods in the testbench is impractical, since this project would be used with 20 years worth of legacy code.
Just change the Aries constructor to take a Taurus reference, instead of the private int directly. Like so:
class Aries;
class Taurus {
friend class Aries;
public:
void setLeo(int inLeo) {
leo = inLeo;
}
private:
int leo;
};
class Aries {
public:
Aries(const Taurus& inTau) : Cancer(inTau.leo) {}
private:
const int& Cancer;
};
int main() {
Taurus t;
Aries a(t);
}
I know you know that friend is questionable but sometimes necessary, but in this case, these classes don't have to be friends.
struct AriesBinder {
AriesBinder(const int& c) : Cancer(c) {}
const int& Cancer;
};
class Taurus {
public:
void setLeo(int inLeo) {
Leo = inLeo;
}
AriesBinder bind() const { return AriesBinder(Leo); }
private:
int Leo;
};
class Aries {
public:
Aries(const int& inCancer) : Cancer(inCancer) {}
Aries(AriesBinder b) : Cancer(b.Cancer) {}
private:
const int& Cancer;
};
int main() {
Taurus t;
Aries b(t.bind()); // Intention was made clear
}
This is especially useful if many objects like Taurus can be bound to Aries. Also, it decouples the both classes since now the don't have to know each other so you may change the internal representation of Taurus.
The purpose of friendship is to allow access to certain classes that are tightly coupled with yours, often class factories (which assign the members as they construct the class) or some special implementation class.
Therefore in your case, if Aries is a friend of Taurus, you would expect there to be a strong coupling between the two.
Your code doesn't work because you are accessing Taurus.Leo from main, not from Aries.
The purpose of the friendship is particularly to NOT have to create a public "getter" for these variables. That is because these variables are "internal detail" that you do not want the public at large to access, not even to read.
So whilst I'd expect most of the answers above to be possible solutions and will compile and work, you have to understand the concept of friendship and design for your particular case to see if it is an appropriate use.

Why would one use nested classes in C++?

Can someone please point me towards some nice resources for understanding and using nested classes? I have some material like Programming Principles and things like this IBM Knowledge Center - Nested Classes
But I'm still having trouble understanding their purpose. Could someone please help me?
Nested classes are cool for hiding implementation details.
List:
class List
{
public:
List(): head(nullptr), tail(nullptr) {}
private:
class Node
{
public:
int data;
Node* next;
Node* prev;
};
private:
Node* head;
Node* tail;
};
Here I don't want to expose Node as other people may decide to use the class and that would hinder me from updating my class as anything exposed is part of the public API and must be maintained forever. By making the class private, I not only hide the implementation I am also saying this is mine and I may change it at any time so you can not use it.
Look at std::list or std::map they all contain hidden classes (or do they?). The point is they may or may not, but because the implementation is private and hidden the builders of the STL were able to update the code without affecting how you used the code, or leaving a lot of old baggage laying around the STL because they need to maintain backwards compatibility with some fool who decided they wanted to use the Node class that was hidden inside list.
Nested classes are just like regular classes, but:
they have additional access restriction (as all definitions inside a class definition do),
they don't pollute the given namespace, e.g. global namespace. If you feel that class B is so deeply connected to class A, but the objects of A and B are not necessarily related, then you might want the class B to be only accessible via scoping the A class (it would be referred to as A::Class).
Some examples:
Publicly nesting class to put it in a scope of relevant class
Assume you want to have a class SomeSpecificCollection which would aggregate objects of class Element. You can then either:
declare two classes: SomeSpecificCollection and Element - bad, because the name "Element" is general enough in order to cause a possible name clash
introduce a namespace someSpecificCollection and declare classes someSpecificCollection::Collection and someSpecificCollection::Element. No risk of name clash, but can it get any more verbose?
declare two global classes SomeSpecificCollection and SomeSpecificCollectionElement - which has minor drawbacks, but is probably OK.
declare global class SomeSpecificCollection and class Element as its nested class. Then:
you don't risk any name clashes as Element is not in the global namespace,
in implementation of SomeSpecificCollection you refer to just Element, and everywhere else as SomeSpecificCollection::Element - which looks +- the same as 3., but more clear
it gets plain simple that it's "an element of a specific collection", not "a specific element of a collection"
it is visible that SomeSpecificCollection is also a class.
In my opinion, the last variant is definitely the most intuitive and hence best design.
Let me stress - It's not a big difference from making two global classes with more verbose names. It just a tiny little detail, but imho it makes the code more clear.
Introducing another scope inside a class scope
This is especially useful for introducing typedefs or enums. I'll just post a code example here:
class Product {
public:
enum ProductType {
FANCY, AWESOME, USEFUL
};
enum ProductBoxType {
BOX, BAG, CRATE
};
Product(ProductType t, ProductBoxType b, String name);
// the rest of the class: fields, methods
};
One then will call:
Product p(Product::FANCY, Product::BOX);
But when looking at code completion proposals for Product::, one will often get all the possible enum values (BOX, FANCY, CRATE) listed and it's easy to make a mistake here (C++0x's strongly typed enums kind of solve that, but never mind).
But if you introduce additional scope for those enums using nested classes, things could look like:
class Product {
public:
struct ProductType {
enum Enum { FANCY, AWESOME, USEFUL };
};
struct ProductBoxType {
enum Enum { BOX, BAG, CRATE };
};
Product(ProductType::Enum t, ProductBoxType::Enum b, String name);
// the rest of the class: fields, methods
};
Then the call looks like:
Product p(Product::ProductType::FANCY, Product::ProductBoxType::BOX);
Then by typing Product::ProductType:: in an IDE, one will get only the enums from the desired scope suggested. This also reduces the risk of making a mistake.
Of course this may not be needed for small classes, but if one has a lot of enums, then it makes things easier for the client programmers.
In the same way, you could "organise" a big bunch of typedefs in a template, if you ever had the need to. It's a useful pattern sometimes.
The PIMPL idiom
The PIMPL (short for Pointer to IMPLementation) is an idiom useful to remove the implementation details of a class from the header. This reduces the need of recompiling classes depending on the class' header whenever the "implementation" part of the header changes.
It's usually implemented using a nested class:
X.h:
class X {
public:
X();
virtual ~X();
void publicInterface();
void publicInterface2();
private:
struct Impl;
std::unique_ptr<Impl> impl;
}
X.cpp:
#include "X.h"
#include <windows.h>
struct X::Impl {
HWND hWnd; // this field is a part of the class, but no need to include windows.h in header
// all private fields, methods go here
void privateMethod(HWND wnd);
void privateMethod();
};
X::X() : impl(new Impl()) {
// ...
}
// and the rest of definitions go here
This is particularly useful if the full class definition needs the definition of types from some external library which has a heavy or just ugly header file (take WinAPI). If you use PIMPL, then you can enclose any WinAPI-specific functionality only in .cpp and never include it in .h.
I don't use nested classes much, but I do use them now and then. Especially when I define some kind of data type, and I then want to define a STL functor designed for that data type.
For example, consider a generic Field class that has an ID number, a type code and a field name. If I want to search a vector of these Fields by either ID number or name, I might construct a functor to do so:
class Field
{
public:
unsigned id_;
string name_;
unsigned type_;
class match : public std::unary_function<bool, Field>
{
public:
match(const string& name) : name_(name), has_name_(true) {};
match(unsigned id) : id_(id), has_id_(true) {};
bool operator()(const Field& rhs) const
{
bool ret = true;
if( ret && has_id_ ) ret = id_ == rhs.id_;
if( ret && has_name_ ) ret = name_ == rhs.name_;
return ret;
};
private:
unsigned id_;
bool has_id_;
string name_;
bool has_name_;
};
};
Then code that needs to search for these Fields can use the match scoped within the Field class itself:
vector<Field>::const_iterator it = find_if(fields.begin(), fields.end(), Field::match("FieldName"));
One can implement a Builder pattern with nested class. Especially in C++, personally I find it semantically cleaner. For example:
class Product{
public:
class Builder;
}
class Product::Builder {
// Builder Implementation
}
Rather than:
class Product {}
class ProductBuilder {}
I think the main purpose of making a class to be nested instead of just a friend class is the ability to inherit nested class within derived one. Friendship is not inherited in C++.
You also can think about first class ass type of main function, where You initiate all needed classes to work togheter. Like for example class Game, initiate all other classes like windows, heroes, enemy's, levels and so on. This way You can get rid all that stuff from main function it self. Where You can create obiect of Game, and maybe do some extra external call not related to Gemente it self.

Conflict between providing (optional) functionality and encapsulation?

I need to provide a certain operation on the elements of my class Foo. This operation is specific and weird enough that I don't really want to make it a member function. On the other hand, it works on the internals of the class, which I don't want to expose.
Here is the class:
class Foo {
typedef std::map<int,double> VecElem;
std::vector<VecElem> vec_;
public:
void Insert(std::size_t index0, int index1, double d);
// ... other essential functions
};
void Foo::Insert(std::size_t index0, int index1, double d) {
vec_[index0][index1] = d;
}
The operation I need to support is to map the index1 of each element inserted so far to a new index, according to a given old-to-new index map:
void MapIndex1(const std::map<std::size_t,std::size_t>& old_to_new);
Given how Foo currently stores its elements this means a complete restructuring of the internal data, but this should not be exposed to the user. But also it shouldn't be a member function.
Is this a typical case of a friend non-member function? Are there any other possibilities? I don't really like the concept of a friend non-member function, because this weird function (which might be only temporarily necessary as a workaround for some problem) will still need to be mentioned inside the "official" class body (which is supposed to never change). But I guess I can't get around that?
What about a public nested class to do the work? Then it could have a MapIndex1 function that automatically gains access to the private members of its enclosing class. When you're done, just remove the nested class.
class Foo {
// ...
public:
void Insert(std::size_t index0, int index1, double d);
// ... other essential functions
class Remapper
{
public:
Remapper(Foo& foo) : foo_(foo) { }
void MapIndex1(const std::map<std::size_t,std::size_t>& old_to_new);
private:
Foo& foo_;
};
};
Foo myFoo;
Foo::Remapper remapper(myFoo);
remapper.MapIndex1(...);
An idea for dealing with this scenario is to add a function like:
void Ioctl(int func, void* params); to your class. This function can then be used as a gateways for all of these hackey temporary scenarios as they arise. They can then be safely removed when the requirement disappears without breaking compatibility (unless of course someone unofficially uses them).
True you do lose type safety but it does provide a nice swiss army knife approach for all such problems.
Internally you can define certain integer func values to call a function and cast the params value to whatever you need.