Reputation: 9179
So, I am willing to structure my project like that:
ClassA.cpp:
class ClassA {
public:
static ClassA* create() {
return new ClassA();
}
void methodA() {
// stuff here
}
void methodB() {
// more stuff here
}
private:
ClassA() {
}
void privateMethodOne() {
//yadda yadda
}
int attributeA;
char attributeB;
};
ClassA.hpp:
class ClassA {
public:
ClassA* create();
void methodA();
void methodB();
private:
ClassA();
};
I am going to work only with pointers, I wonder if this approach would generate an error in a future. I wonder if there is a pitfall here. Suppose that the .hpp is automatically generated so it would have exactly the same members, except the private ones.
Upvotes: 1
Views: 544
Reputation: 1598
As the OP expressed a wish to:
"...hide the private attributes so you dont have to deploy new headers if the amount of attributes changes"
then I would solve this by seperating interface from implementation. You expose the interface and hide the implementation.
What you could expose to those needing to use the class is a thin interface instead of a class declaration. A thin interface in C++ is best described with pure virtual functions. You would also expose a function which returns the object that implements this interface.
Firstly the header file which exposes your API. This is all the users of the service will see:
struct Interface1 {
virtual ~Interface1() {}
virtual void methodA()=0;
};
Interface1* createInstanceOfInterface1();
Then in files that the user of your service does not see we have the implementation:
class Interface1Impl : public Interface1 {
private:
int nTopSecretMemberVar;
public:
virtual void methodA() {
//implement it
}
};
Interface1* createInstanceOfInterface1() {
return new Interface1Impl();
}
And the usage of your API by the peoplse using the service who are not exposed to the details of the implementation, as follows:
void test() {
Interface1* p = createInstanceOfInterface1();
p->methodA();
}
This becomes a particularly valuable practice when it makes sense to place the implementation of such services in DLLs or shared libraries that can be plugged and played at run time. It yields many benefits.
Upvotes: 1
Reputation: 272537
This approach is not valid. C++ has the one definition rule. See C++03 section 3.2 for full details, but here is Wikipedia's summary (highlighting is mine):
In short the ODR states that:
- In any translation unit, a template, type, function, or object can have no more than one definition. Some of these can have any number of declarations. A definition provides an instance.
- In the entire program, an object or non-inline function cannot have more than one definition; if an object or function is used, it must have exactly one definition. You can declare an object or function that is never used, in which case you don't have to provide a definition. In no event can there be more than one definition.
- Some things, like types, templates, and extern inline functions, can be defined in more than one translation unit. For a given entity, each definition must be the same. Non-extern objects and functions in different translation units are different entities, even if their names and types are the same.
You may be looking for the PIMPL idiom, which is a way to "hide" private members from the public interface (i.e. the public header file).
Upvotes: 6