Is it possible to forward declare a class member variable? I want to do something like the following (But it doesn't work):
class myClass;
bool myClass::myvar;
void main()
{
myClass* aaa;
...
aaa->myvar = false;
}
In this example, myvar is a boolean member of myClass.
No, you can't. Imagine the class is scattered across different translation units this way.
What members will it have then? And what will be the object layout?
That's intractable.
I would recommend to use set/get methods in this case. Then you don't expose your internal data to the outside world.
In the header of myClass:
class myClass
{
public: setMyVar(const bool& value);
public: inline const bool& getMyVar() const;
private: bool myVar;
};
In your implementation:
class myClass;
void main()
{
myClass* aaa;
...
aaa->setMyVar(false);
}
Related
So consider I have a class with a private member variable and a private function which I do not want to define in the header file, because I want to "hide" it from the user.
How can I make this? I can not access the private variable without the declaration of the function in the header.
So what works is something like this:
// header file
class Testclass {
public:
// ...
private:
const int m_i;
void func() const;
}
// cpp file
#include "TestClass.h"
Testclass::func() const {
int j = m_i; //access to a private member variable
}
// ...
But I want something like this:
// header file
class Testclass{
public:
//...
private:
const int m_i;
}
// cpp file
#include "TestClass.h"
Testclass::func() const {
int j = m_i; //access to a private member variable
}
// ...
Which possibilities do I have? I read something about the PIMPL Idiom, but I am not sure if this is what I want, since it looks a bit cumbersome coding-wise.
You can have non-member helper functions in the cpp file, that the class members can use. However, they would have to pass the private variable as a parameter.
// header file
class Testclass{
public:
//...
private:
const int m_i;
}
// cpp file
#include "TestClass.h"
void func(int m_i) {
int j = m_i; //private member variable supplied by caller
}
// ...
Normally one achieves this through the PIMPL (Pointer to IMPLementation) idiom. In your header file you have:
class MainClass
{
public:
void public_function();
private:
class Impl;
Impl* impl;
};
Note that the header file does not contain the definition of the Impl class, only its declaration.
You then define that class in your cpp file and forward the calls from your public interface to the functions of the impl class:
class MainClass::Impl
{
void actualfunc()
{
//do useful stuff here
}
};
void MainClass::public_function()
{
return impl->actualfunc();
}
Apart from your indended hiding of unwanted members from your class users, the PIMPL idiom provides the additional benefit that if no changes are made to the interface of the class, the users of the class need not be recompiled.
If a class has lots of private functions it seems undesirable to have them declared in the header file. It makes it harder for clients to parse the interface of the class and it increases compilation time.
One option is, of course, the pimpl idiom, but that adds a layer of indirection and also results in a memory allocation.
What follows is a example of hiding helper functions in a friend class that is defined in the implementation file.
Is there a name for this idiom?
Is there any reason not to do it?
//Foo.h
class Foo
{
public:
void FuncA();
void FuncB();
private:
int x;
// more data...
friend struct FooHelpers;
};
//Foo.cpp
struct FooHelpers
{
static void Helper1(Foo& f)
{
// manipulate private data..
f.x++; //etc.
}
// Possibly more funcs...
};
void Foo::FuncA()
{
//....
FooHelpers::Helper1(*this);
//....
}
//....
Is there a name for the idiom of using a friend class to hide what would have been private functions?
The Attorney-Client idiom.
Is there any reason not to do it?
As suggested also in some comments, here's a reason not to do it: while it provides a patterned option, it avoids dealing with the root of the problem - the design of the original class (class Foo).
In your question you write:
If a class has lots of private functions it seems undesirable to have them declared in the header file.
There's some subjectivity to this question so allow me to restate it more objectively with the following question.
Are there ways to avoid private member functions?
You pointed out one way, to use the PIMPL idiom. As also suggested in some comments, here's some more:
Refactor the original (a.k.a. client) class to instead use non-member non-friend functions or lambda expressions that manipulate your class member data through parameters - so that it doesn't need private member functions.
Split up the class into multiple smaller classes so that each of the smaller classes declares less of the original class's private member functions. Like with member data, the more private member functions a class has, the more likely - at least in my opinion - the class is violating the single responsibility principal. So this kind of effort can reduce the private member functions as well making your class design more robust.
Say we start with the following code:
//Foo.h
class Foo
{
public:
void FuncA();
void FuncB();
private:
void multiplyByTwo();
int x;
// more data...
};
//Foo.cpp
void Foo::multiplyByTwo()
{
x = x * 2;
}
void Foo::FuncA()
{
multiplyByTwo();
}
Here's an example using the first way of what this could be changed to:
//Foo.h
class Foo
{
public:
void FuncA();
void FuncB();
private:
int x;
// more data...
};
//Foo.cpp
namespace {
int multiplyByTwo(int x)
{
return x * 2;
}
}
void Foo::FuncA()
{
x = multiplyByTwo(x);
}
In addition to eliminating the declaration of multiplyByTwo as a private member function of class Foo, this change also more idiomatically expresses the intention of the multiplyByTwo function in now saying in C++ syntax what's its input and output.
I create a basic IBasic interface with a static field
class IBasic
{
public:
IBasic();
virtual ~IBasic();
static std::vector< std::vector<char> > Field;
};
from which the Inherit class is inherited:
class Inherit : public IBasic
{
public:
Inherit(int);
~Inherit();
void Foo();
};
The Inherit class makes some manipulations with Field static member in constructor/or member function.
In order to create an instance of the Inherit class, we need to explicitly declare a static field in the main.cpp before the main function:
#include "Basic.h"
#include "Inherit.h"
std::vector< std::vector<char> > IBasic::Field;
int main()
{
Inherit(10);
return 0;
}
The questions are:
In what namespace does the static method actually exists (global?)? Because I know that static field/function is not a class member in fact.
Is there another way to declare this static method, for example, in a
class file, inside a main function, or through creation unnamed namespace? Is it only one right variant?
How is right? What should be considered first of all?
A static member of a class is a member of its class (that's a tautology) and its class namespace (a class is a namespace). It is not a nember of any other namespace.
A non-const static data member of a class must be defined exactly once in a program, outside of any class, in the same namespace its class is defined in (a global namespace in your case). A header file is inappropriate place for such declaration. It is normally placed in an implementation .cpp file that goes together with the header file.
Having said that, an interface should not have any static data members, much less public ones. It is most likely a grave design error.
In what namespace does the static method actually exists (global?)? Because I know that static field/function is not a class member in fact.
It is declared in scope of the class. In fact the static variable is a class member, your assumption is wrong.
Is there another way to declare this static method, for example, in a class file, inside a main function, or through creation unnamed namespace? Is it only one right variant?
The usual way is to define it in the translation unit that contains the function definitions for the class.
How is right? What should be considered first of all?
There's no right or wrong way, but as mentioned definition in the same translation unit as the class function definitions is the usual way.
Here's an example usage of a static member without any inheritance.
SomeClass.h
#ifndef SOME_CLASS_H
#define SOME_CLASS_H
class SomeClass {
private:
int x;
public:
static SomeClass* const get(); // Needed For Using class to get this pointer
SomeClass();
int getX() const { return x; }
void setX( int val ) { x = val; }
};
#endif // SOME_CLASS_H
SomeClass.cpp
#include "SomeClass.h"
static SomeClass* s_pSomeClass = nullptr;
SomeClass::SomeClass() {
s_pSomeClass = this;
}
SomeClass* const SomeClass::get() {
if ( nullptr == s_pSomeClass ) {
// throw exception
}
return s_pSomeClass;
}
Another class using above class as a static member
OtherClass.h
#ifndef OTHER_CLASS_H
#define OTHER_CLASS_H
class SomeClass; // Forward Declaration
class OtherClass {
private:
static SomeClass* pSomeClass; // The Static Member to this class
int y;
public:
OtherClass();
int getY() const { return y; }
void setY( int val ) { y = val; }
void useSomeClassToSetY();
};
#endif // OTHER_CLASS_H
OtherClass.cpp
#include "OtherClass.h"
#include "SomeClass.h"
SomeClass* OtherClass::pSomeClass = nullptr;
OtherClass::OtherClass() {
if ( nullptr == pSomeClass ) {
pSomeClass = SomeClass::get();
}
}
void OtherClass::useSomeClassToSetY() {
// First Set X To Some Value:
pSomeClass->setX( 10 ); // Use of Static Member
y = pSomeClass->getX(); // Use of Static Member
}
Static members still belong to the class, but they have static storage.
Consider these two classes that employ the Pimpl idiom:
ClassA: Pimpl class forward declaration and variable declaration on separate lines
ClassA.h:
#include <memory>
class ClassA {
public:
ClassA();
~ClassA();
void SetValue( int value );
int GetValue() const;
private:
class ClassA_Impl;
// ^^^^^^^^^^^^^^ class forward declaration on its own line
std::unique_ptr<ClassA_Impl> m_pImpl;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable declaration on its own line
//EDIT:
//Even if we use a raw pointer instead of a smart pointer,
//i.e. instead of declaring the smart pointer above, if we declare:
ClassA_Impl *m_pImpl;
//the situation in the *.cpp files and my questions (below) are the same.
};
ClassA.cpp:
#include "ClassA.h"
class ClassA::ClassA_Impl {
public:
void SetValue( int value );
int GetValue() const;
private:
int value_;
};
// Private class implementation
void
ClassA::ClassA_Impl::SetValue( int value ) {
value_ = value;
}
int
ClassA::ClassA_Impl::GetValue() const {
return value_;
}
// ClassA implementation
ClassA::ClassA() : m_pImpl( new ClassA_Impl() ) {}
ClassA::~ClassA() {}
void
ClassA::SetValue( int value ) {
m_pImpl->SetValue( value );
}
int
ClassA::GetValue() const {
return m_pImpl->GetValue();
}
ClassB: Pimpl class forward declaration and variable declaration on one line
ClassB.h:
#include <memory>
class ClassB {
public:
ClassB();
~ClassB();
void SetValue( int value );
int GetValue() const;
private:
std::unique_ptr<class ClassB_Impl> m_pImpl;
// ^^^^^^^^^^^^^^^^^^ class forward declaration
// combined with variable declaration on one line,
// in one shot.
//EDIT:
//Even if we use a raw pointer instead of a smart pointer,
//i.e. instead of declaring the smart pointer above, if we declare:
class ClassB_Impl *m_pImpl;
//the situation in the *.cpp files and my questions (below) are the same.
};
ClassB.cpp:
#include "ClassB.h"
class ClassB_Impl {
public:
void SetValue( int value );
int GetValue() const;
private:
int value_;
};
// Private class implementation
void
ClassB_Impl::SetValue( int value ) {
value_ = value;
}
int
ClassB_Impl::GetValue() const {
return value_;
}
// ClassB implementation
ClassB::ClassB() : m_pImpl( new ClassB_Impl() ) {}
ClassB::~ClassB() {}
void
ClassB::SetValue( int nValue ) {
m_pImpl->SetValue( nValue );
}
int
ClassB::GetValue() const {
return m_pImpl->GetValue();
}
Questions:
Why does combining the forward declaration and variable declaration on one line in ClassB.h require ClassB_Impl to be "unscoped" in the implementation of the private class in ClassB.cpp?
i.e. in ClassA.cpp, private class method definitions begin with
void ClassA::ClassA_Impl::foo() {...
but in ClassB.cpp, private class method definitions begin with
void ClassB_Impl::foo() {...
What are the implications of each method? Which one is better?
(Follow-up question in response to Galik's answer)
When you combine forward declaration of a class and declaration of a variable of that class in one statement...
//one-liner
class ClassB_Impl *m_pImpl;
...what is this called? Is there a name for this kind of combined statement? And why exactly doesn't ClassB_Impl become an inner class of ClassB as a result of such a statement?
Compare this to...
//two-liner
class ClassA_Impl;
ClassA_Impl *m_pImpl;
...in which case ClassA_Impl does become an inner class of ClassA.
Why does the one-liner put ClassB_Impl into the global namepace, while the two-liner puts ClassA_Impl into ClassA's namespace? Why are they different?
Why does combining the forward declaration and variable declaration on
one line in ClassB.h require ClassB_Impl to be "unscoped" in the
implementation of the private class in ClassB.cpp?
Because in the first example you declare ClassA_Impl as an inner class of ClassA.
When you declare ClassB_Impl it in the template parameter that is not part of ClassB.
What are the implications of each method? Which one is better?
This is a matter of opinion. Personally I think inner classes are messy and harder to work with for little reward.
My preferred method uses a separate interface class which helps to reduce the number of times you have to redeclare the interface.
See: Is it possible to write an agile Pimpl in c++?
A C++ n00b question. Is it possible to call a private constructor from a static method defined in the cpp? I'd like to keep methods out of the header file if possible -- I figure there should be a way to do this. I'm getting an error when attempting this:
"cannot access private member declared in class SomeClass"
/////////////////
// SomeClass.h //
/////////////////
class SomeClass {
public:
static SomeClass SomeMethod();
private:
SomeClass(int i);
}
///////////////////
// SomeClass.cpp //
///////////////////
static SomeClass OSImplementation() {
return SomeClass(0);
};
// calls implementation
SomeClass SomeClass::SomeMethod() {
return OSImplementation();
}
You can make OSImplementation a friend method.
Or you can make OSImplementation a static method within the class (but that has to be declared in the header).
Or, probably the most common way to do this, is to have an internal implementation class, like this:
class SomeClass {
public:
//...
private:
struct Impl;
Impl* intern;
};
In your cpp file, you declare struct SomeClass::Impl.
In your constructor, create the SomeClass::Impl instance. Delete it in the destructor. And implement the copy-constructor and the assignment operator!
This is called the PIMPL (pointer to implementation) idiom (Wikipedia, c2.com). It's used a lot in big projects like Qt.
Yes, it is possible, by making the OSImplementation() friend of SomeClass. Next example compiles without warnings and errors using g++ 4.6.1 :
#include <iostream>
// declare in hpp
class SomeClass {
friend SomeClass OSImplementation();
public:
static SomeClass SomeMethod();
void foo();
private:
SomeClass(int);
};
int main()
{
auto obj = SomeClass::SomeMethod();
obj.foo();
}
// define in cpp
SomeClass SomeClass::SomeMethod(){
return SomeClass( 5 );
}
SomeClass::SomeClass(int){
}
void SomeClass::foo(){
std::cout<<"foo"<<std::endl;
}
SomeClass OSImplementation()
{
return SomeClass::SomeMethod();
}