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.
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).
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.
This is actually double definition of class A
Related
I'm trying to use interface classes and I have the following class structure:
IBase.h:
#pragma once
class IBase
{
protected:
virtual ~IBase() = default;
public:
virtual void Delete() = 0;
IBase& operator=(const IBase&) = delete;
};
IQuackable.h:
#ifndef IQUACKABLE
#define IQUACKABLE
#include "IBase.h"
#include <iostream>
class IQuackable : public IBase
{
protected:
IQuackable() = default;
~IQuackable() = default;
public:
virtual void Quack() = 0;
static IQuackable* CreateInstance();
};
#endif //
MallardDuck.h:
#pragma once
#include "IQuackable.h"
class MallardDuck : public IQuackable
{
private:
MallardDuck();
protected:
~MallardDuck();
public:
void Delete() override;
void Quack() override;
friend IQuackable* IQuackable::CreateInstance();
};
MallardDuck.cpp:
#include "MallardDuck.h"
MallardDuck::MallardDuck() {}
MallardDuck::~MallardDuck() {}
void MallardDuck::Delete() { delete this; }
void MallardDuck::Quack()
{
std::cout << "Quack!\n";
}
IQuackable* IQuackable::CreateInstance()
{
return static_cast<IQuackable*>(new MallardDuck());
}
Also I've created class RedHeadDuck.h and .cpp with the same declaration and definition as MallardDuck.
And, finaly, main class code:
#include "MallardDuck.h"
#include "RedHeadDuck.h"
int main()
{
IQuackable* mallardDuck = MallardDuck::CreateInstance();
IQuackable* redHeadDuck = RedHeadDuck::CreateInstance();
mallardDuck->Quack();
redHeadDuck->Quack();
}
And here I got two errors:
LNK2005 "public: static class IQuackable * __cdecl IQuackable::CreateInstance(void)" (?CreateInstance#IQuackable##SAPAV1#XZ) already defined in MallardDuck.obj".
LNK1169 "one or more multiply defined symbols found".
As I find out, the problem is in double definition, but how it fix?
I've read about Header guards, but, as I understood, it can't help in this case. Also people write about inline functions, but I've not realized how it may be used here.
What can I do?
Goals
I suppose these are what you are trying to obtain by adopting all the complicated patterns:
interface, i.e., "multiple types, same set of methods"
some sort of abstract factory pattern, i.e., you want a "instantiator" who provides a static method (which is not very different from a global function) to call, and returns instances of derived classes
prohibit users from directly calling the ctors of derived classes
take care of the dtors by implementing the Delete() method
Requirement 1-3
There are at least 3 ways to meet requirement 1-3, as explained below:
1. Derived classes hiding static method of their base
This is the easiest way, and it's fully capable of current main.cpp. Derived classes can override static methods of their base class.
In file MallardDuck.h and RedHeadDuck.h:
// Replace this:
// friend IQuackable* IQuackable::CreateInstance();
// With this:
static IQuackable* CreateInstance();
In file MallardDuck.cpp (and RedHeadDuck.cpp similarly):
// Replace this:
// IQuackable* IQuackable::CreateInstance() {
// return static_cast<IQuackable*>(new MallardDuck());
// }
// With this:
IQuackable* MallardDuck::CreateInstance() {
return new MallardDuck();
}
The problem with this is that: other derived classes that don't override and hide CreateInstance() will still expose IQuackable::CreateInstance() as a "fallback". Thus:
if you don't actually implement IQuackable::CreateInstance() (so far, you don't have to), then once it is called via a derived class, the code won't compile and won't give a reason that's comprehensible to others; or
if you choose to implement it, you'd better throw an exception within it, which may surprise your user; otherwise you would have to return a nullptr or something, which is the worst practice in C++ (that's what we do in C since it has no language-level support for error handling; any C++ function that cannot fulfill its job should never return).
Either way is not elegant.
2. Adopt abstract factory pattern
This pattern requires a cooperating "factory class", which is abstract; then whenever you derive a concrete quackable, derive also its factory.
In your case you'll need to sketch out a IQuackableFactory, exposing IQuackableFactory::CreateInstance(), then derive a MallardDuckFactory and a RedHeadDuckFactory.
There are plenty of good examples already, so I won't demonstrate here.
3. Feature injection by using CRTP
There's yet another way of doing things. By CreateInstance() you're actually providing a "Give me an instance of this class!" feature. Typically we use the CRTP (curiously recurring template pattern) to "inject" a certain feature into a class.
First write this file EnableCreateInstance.hpp:
#ifndef _ENABLECREATEINSTANCE_HPP_
#define _ENABLECREATEINSTANCE_HPP_
template <class T>
struct EnableCreateInstance {
static T* CreateInstance() { return new T(); }
};
#endif //_ENABLECREATEINSTANCE_HPP_
Then in MallardDuck.h:
// Add:
#include "EnableCreateInstance.hpp"
class MallardDuck : public IQuackable, public EnableCreateInstance<MallardDuck> {
private:
MallardDuck();
friend class EnableCreateInstance<MallardDuck>;
...
In file RedHeadDuck.h do the similar: include header, publicly inherit EnableCreateInstance<RedHeadDuck>, and declare EnableCreateInstance<RedHeadDuck> as friend class.
This provides more flexibility: you're still providing an interface CreateInstance(), but in a less "aggressive" way: derived classes have their freedom to choose whether or not to provide CreateInstance(). If they do, just inherit and (if ctor made private) declare friendship; if not, omit the additional inheritance.
Requirement 4
Well, actually you can use delete this in non-static non-dtor method. But:
You must ensure (which can be difficult) that no more access to the deleted object's data members or virtual functions are made, otherwise it causes undefined behaviors;
You leave your users with dangling pointers to the deleted object.
So, we seldom provide such "deleters" in modern C++. You can get all the benefits it may provide through smart pointers, plus the ability to avoid UBs and so much more.
If you have a feature rich class, possibly one you do not own/control, it is often the case where you want to add some functionality so deriving makes sense.
Occasionally you want to subtract as well, that is disallow some part of the base interface. The common idiom I have seen is to derive and make some member functions private and then not implement them. As follows:
class Base
{
public:
virtual void foo() {}
void goo() { this->foo(); }
};
class Derived : public Base
{
private:
void foo();
};
someplace else:
Base * b= new Derived;
and yet another place:
b->foo(); // Any way to prevent this at compile time?
b->goo(); // or this?
It seems that if the compilation doesn't know that it is derived, the best you can do is not implement and have it fail at runtime.
The issue arises when you have a library, that you can't change, that takes a pointer to base, and you can implement some of the methods, but not all. So part of the library is useful, but you run the risk of core dumping if you don't know at compile time which functions will call what.
To make it more difficult, others may inherit from you class and want to use the library, and they may add some of the functions you didn't.
Is there another way? in C++11? in C++14?
Let's analyze this, focused on two major points:
class Base
{
public:
virtual void foo() {} // This 1)
// ...
class Derived : public Base // and this 2)
In 1) you tell the world that every object of Base offers the method foo() publicly. This implies that when I have Base*b I can call b->foo() - and b->goo().
In 2) you tell the world that your class Derived publicly behaves like a Base. Thus the following is possible:
void call(Base *b) { b->foo(); }
int main() {
Derived *b = new Derived();
call(b);
delete b;
}
Hopefully you see that there is no way call(Base*) can know if b is a derived and thus it can't possibly decide at compile-time if calling foo wouldn't be legal.
There are two ways to handle this:
You could change the visibility of foo(). This is probably not what you want because other classes can derive from Base and someone wants to call foo afterall. Keep in mind that virtual methods can be private, so you should probably declare Base as
class Base
{
virtual void foo() {}
public:
void goo() { this->foo(); }
};
You can change Derived so that it inherits either protected or private from Base. This implies that nobody/only inheriting classes can "see" that Derived is a Base and a call to foo()/goo() is not allowed:
class Derived : private Base
{
private:
void foo() override;
// Friends of this class can see the Base aspect
// .... OR
// public: // this way
// void foo(); // would allow access to foo()
};
// Derived d; d.goo() // <-- illegal
// d.foo() // <-- illegal because `private Base` is invisible
You should generally go with the latter because it doesn't involve changing the interface of the Base class - the "real" utility.
TL;DR: Deriving a class is a contract to provide at least that interface. Subtraction is not possible.
This seems to be what you want to do:
struct Library {
int balance();
virtual int giveth(); // overrideable
int taketh(); // part of the library
};
/* compiled into the library's object code: */
int Library::balance() { return giveth() - taketh(); }
/* Back in header files */
// PSEUDO CODE
struct IHaveABadFeelingAboutThis : public Library {
int giveth() override; // my implementation of this
int taketh() = delete; // NO TAKE!
};
So that you can't call taketh() on an IHaveABadFeelingAboutThis even when it is cast as the base class.
int main() {
IHaveABadFeelingAboutThis x;
Library* lib = &x;
lib->taketh(); // Compile error: NO TAKE CANDLE!
// but how should this be handled?
lib->balance();
}
If you want to present a different interface than the underlying library you need a facade to present your interface instead of the that of the library.
class Facade {
struct LibraryImpl : public Library {
int giveth() override;
};
LibraryImpl m_impl;
public:
int balance() { return m_impl.balance(); }
virtual int giveth() { return m_impl.giveth(); }
// don't declare taketh
};
int main() {
Facade f;
int g = f.giveth();
int t = f.taketh(); // compile error: undefined
}
Although I don't think your overall situation is good design, and I share many of the sentiments in the comments, I can also appreciate that a lot of code you don't control is involved. I don't believe there is any compile time solution to your problem that has well defined behavior, but what is far preferable to making methods private and not implementing them is to implement the entire interface and simply make any methods you can't cope with throw an exception. This way at least the behavior is defined, and you can even do try/catch if you think you can recover from a library function needing interface you can't provide. Making the best of a bad situation, I think.
If you have class A:public B, then you should follow the https://en.wikipedia.org/wiki/Liskov_substitution_principle
The Liskov substitution principle is that a pointer-to-A can be used as a pointer-to-B in all circumstances. Any requirements that B has, A should satisfy.
This is tricky to pull off, and is one of the reasons why many consider OO-style inheritance far less useful than it looks.
Your base exposes a virtual void foo(). The usual contract means that such a foo can be called, and if its preconditions are met, it will return.
If you derive from base, you cannot strengthen the preconditions, nor relax the postconditions.
On the other hand, if base::foo() was documented (and consumers of base supported) the possibility of it throwing an error (say, method_does_not_exist), then you could derive, and have your implementation throw that error. Note that even if the contract says it could do this, in practice if this isn't tested consumers may not work.
Violating the Liskov substitution principle is a great way to have lots of bugs and unmaintainable code. Only do it if you really, really need to.
What I've seen and been taught about encapsulation is that we can have data members as private and member functions are public.
But C++ Primer defines encapsulation as:
Separation of implementation from interface; encapsulation hides
the implementation details of a type. In C++, encapsulation is enforced by putting the implementation in the private part of a class.
The last line is the confusing part: putting the implementation in the private part of a class. By implementation, he means the function definitions, right? I mean, I've never seen a function declared public (as prototype) and implemented in private.
I'm really confused. Please explain what he's trying to say with a simple example.
The concept being explained is more abstract than you're thinking about it. The "interface" is "what callers expect the object to do". And the implementation is technically how the class actually carries out those operations.
So for example, take a List class. Code that uses a List should only care about its interface: things like addObject(), clear(), getSize(), sort().
But the implementation of List -- which callers should not care about -- may vary drastically on how to accomplish this. For example the data could be stored as a linked list. Or maybe as a dynamic array. This is "private" implementation details that only the List class needs to care about. There will indeed probably be a private: method called reallocate() or so. Callers should never use this; it's an implementation detail -- not part of the public interface. Callers should not care how the List allocates its storage.
Similarly, a sort() method implies it will sort objects in the list. That's the interface. But the implementation may use any number of algorithms to perform the sort. The implementation is a private detail - and may be done in private methods. In any case it's hidden from callers.
template<typename T>
class List
{
public:
// public members are part of the interface: the externally-visible behavior "contract" your object guarantees.
void addObject(const T& obj)
{
// call private methods to help carry out implementation.
ensureCapacity(this->sizeAllocated + 1);
this->sizeAdvertized += 1;
// ... and copy the object into the right position in this->data...
}
size_t getSize() const
{
return this->sizeAdvertized;
}
// ... other members like clear(), sort()...
private:
T* data;
size_t sizeAllocated;
size_t sizeAdvertized;
// this needs to be private because it's not part of the interface. Callers
// should never need to call this.
void ensureCapacity(size_t requestedCapacity)
{
if(sizeAllocated >= requestedCapacity)
return;// already have enough storage available.
// ... reallocate this->data, copy existing items to the new array...
this->sizeAllocated = requestedCapacity;
}
};
And finally to address what you said:
I mean, I've never seen a function declared public (as prototype) and implemented in private.
"Private" again is more abstract than you're thinking. The implementation of a class is basically always "private" in that it's hidden from callers. It doesn't necessarily mean the private: access specifier. It just means that it's not exposed to callers. Implementation of public methods fits this description.
You can indeed have private functions (methods) in a class. Consider:
class X
{
public:
// public interface - this never changes and you provide documentation for it
void do_something();
private:
// this private interface is likely to change. consumers of this class
// are prevented from calling these methods unless they are friends
void first_private_thing();
void second_private_thing();
};
// definition
void X::do_something()
{
// private implementation in public method
first_private_thing();
second_private_thing();
}
there are further extensions on this theme, for example:
class Base
{
public:
// public non-virtual interface
void do_something();
private:
// calls private virtual implementation
virtual void do_something_impl() = 0;
};
// definition:
void Base::do_something()
{
do_something_impl();
}
I have a question about declaration of class.
I read the following lines in a paper: A C++ class declaration combines the external interface of an object with the implementation of that interface.
So, what is a external interface in C++? are there concept of interface in C++? how to understand this: A C++ class declaration combines the external interface of an object with the implementation of that interface. ?
I think it's referring to the API — i.e. the signatures of the public functions — as contrasted to the implementation — i.e. private functions and data members.
class T
{
// Here are some private things.
// You might say that these are part of
// the class's implementation.
int x;
int y;
void foo();
void bar();
public:
// And here are some public things, that
// constitute the class's API or "interface",
// which is the mechanism by which you may
// interact with objects of this type.
void baz();
void boz();
};
Notice how they are all present, right there, in the single class definition, and they must be. "Combined".
Ultimately, though, you'd have to ask the author of the paper as the terminology level used is up to them. Conceivably they could be talking about inheritance heirarchies and abstract base classes... though I can't find a way to rationalise the assertion that C++ class definitions "combine" those in any real sense.
I think the definition by the paper is a bit inaccurate. The terms declaration, implementation, definition, and interface should be used with some rigor. I will try to explain a little bit.
First of all, a class declaration does not specify any interface: it simply states that the class exists. For instance, these are some declarations:
class my_class;
struct my_structure;
template<typename T> class X;
A class definition on the other hand declares which are the members of a class (functions and data). Without entering too much into details, the term external interface in the sense used by the paper you quote roughly means "a specification of what can be done with objects of that class by code which belongs to functions that are not members of that class".
Here is an example of a class definition:
class my_class
{
public:
void foo();
int bar(int x) const;
private:
void do_something();
int data;
};
The term external interface used in the paper you mention almost certainly refers to the public interface, which is the list of all members of the class which have public visibility. All member variables and functions of a class can have one of three levels of visibility: public, protected, or private. I am not delving into details here, but it should be enough to say that public members (data or functions) are those members that can be accessed from functions which are not themselves members of the class, while private members can only be accessed from functions which are members of the class. The protected qualifier is related with inheritance and I don't think that needs to be covered to answer your question.
Now the public interface of class my_class above declares functions foo() and bar(), but does not yet specify their implementation or, in more formal terms, their definition. In general, member functions are not necessarily defined in a class definition (you can't tell what foo() does just by looking at the definition of my_class, can you?). Thus, unless you write the body of a member function directly after its declaration, a separate member function definition is necessary to specify the implementation of that function:
void my_class::foo()
{
std::cout << "hello, i'm foo" << std::endl;
}
int my_class::bar(int x)
{
do_something();
x * 2 + 1;
}
void my_class::do_something()
{
std::cout << "doing something..." << std::endl;
}
Due to the different visibility levels of these functions, a client code from a function external to class my_class can call functions foo() and bar(), because they belong to the public interface, but not function do_something(), which is declared as private. For instance:
int main()
{
my_class c;
c.foo(); // OK!
c.do_something(); // ERROR!
}
The rationale behind the fact that some functions can be made accessible from the outside of a class and other cannot is to be found in a good design principle that goes under the name of "information hiding". By exposing to your clients only a set of services and hiding the way those services are actually implemented (e.g. function bar() invokes the private function do_something()), you create a layer of abstraction that protects client code from possible internal changes in the implementation of those services.
So finally, I believe that what the writer of the sentence "A C++ class declaration combines the external interface of an object with the implementation of that interface" actually wants to say is that from the definition of a class you can get a hint on what are the services that class exposes to its clients ("external interface", i.e. public functions) and what are the functions and variables that are used internally to realize those services ("implementation", i.e. private functions and member variables).
I apologize if it took a bit long to finally give you the interpretation of that sentence, but I felt like some clarification was in order. Anyway, this was necessarily just a short summary of this articulated topic: I am sure you can find better sources if you google all these terms or if you buy a good book on C++.
P.S.: Also please keep in mind, that formally the term (and keyword!) interface means something very specific in C++, which requires introducing the notion of pure virtual function. I thought it was not the case of explaining that, as it was likely unrelated with the intended meaning of the word "interface" in the sentence you quoted.
You could view the public members of a class as an external interface.
There is no interface in C++ as you have it in Java, for example. You can only define a base class and define some virtual member functions, which must be implemented by derived classes.
A class declaration includes public, protected and/or private members. The protected and private members could be seen as "implementation" details, but not necessarily as implementation of that public interface.
The interface contains declaration of the method, and this is found in header files. This header files is correlated with some source files where appear the code for this methods. fr example, you can see how can be add a class in Eclipse CDT.
I am new at building distributable libraries written in C++ and I am getting a bit lost.
I have created a .cpp file with wrappers for all functions I want the library to offer users, and I have written 2 .h files, one public and one private. Below is a dummy example of my header files:
public.h:
class myclass
{
public:
public_function();
private:
}
private.h:
class myclass
{
public:
public_function();
private:
anotherClass instanceofClass;
}
Note that the implementation of public_function() uses the "instanceofClass" in the code.
I have been able to compile with no problem the code using the private class and to compile and link the library with external programs using the public header and the compiled library. When executing that code, though, I am getting segmentation faults that I suspect have to do with lack of proper initialization of "instanceofClass".
Am I doing the right thing? Am I forced to instantiate "instanceofClass" inside the implementation of public_function() for it to be initialized properly, or is there anything else I should do instead?
Thanks a lot.
You can't declare the same class 'myclass' in two different ways. There has to be a single class definition. If you want to hide the implementation's API you want to use the 'Pimpl' idiom. So your public class has a single pointer to a private class. For example:
public.h
class myclass_private;
class myclass {
private:
myclass_private* pimpl;
public:
myclass();
void public_function();
};
public.cpp
myclass::myclass() {
pimpl = new myclass_private;
}
void myclass::public_function() {
pimpl->private_function();
}
private.h
class myclass_private {
public:
void private_function();
};
The myclass defined in public.h has no members, and is therefore sized 1 byte. The myclass defined in private.h encapsulates anotherClass, and is therefore whatever size anotherClass is. This inconsistency is the root of your problem.
What you ought to do is have only one header, and use a pointer (which doesn't require a class definition) to enable hiding the implementation of anotherClass. I'll repeat Joachim's link to the pimpl idiom for elaboration.
The definition of a class shall not changr between different translation units. This is one of the aspects of the One Definition Rule. What you might want to donis to define the publicly visible class to have a pointer to a private implementation: the Pimpl Idiom:
class Public {
public:
...
private:
struct Impl;
Impl* impl_;
};
The struct Impl would only be defined in the implementation file.
Your class lacks a proper constructor, which means that the compiler will provide a default one based on the content of the class definition. If that definition isn't consistent accross all the code, it won't get initialized the same way everywhere, and some data may be missing.
If you want to hide the implementation details of instanceofClass, just do a forward declaration in the header (the private header you're providing is correct, you can use it as your public one), and provide an implementation somewhere in your code.