Friday, June 21, 2019

c++ - How to forward declare a class which is in a namespace



I am trying to use forward declarations in header files to reduce #includes used and hence reduce dependencies where users include my header file.




However, I am unable to forward decalre where namespaces are used. See example below.



a.hpp file:
#ifndef __A_HPP__
#define __A_HPP__

namespace ns1 {

class a {

public:
a(const char* const msg);

void talk() const;

private:
const char* const msg_;
};
}


#endif //__A_HPP__

a.cpp file:
#include

#include "a.hpp"

using namespace ns1;

a::a(const char* const msg) : msg_(msg) {}


void a::talk() const {
std::cout << msg_ << std::endl;
}



consumer.hpp file:
#ifndef __CONSUMER_HPP__
#define __CONSUMER_HPP__


// How can I forward declare a class which uses a namespace
//doing this below results in error C2653: 'ns1' : is not a class or namespace name
// Works with no namespace or if I use using namespace ns1 in header file
// but I am trying to reduce any dependencies in this header file
class ns1::a;

class consumer
{
public:

consumer(const char* const text) : a_(text) {}
void chat() const;

private:
a& a_;
};

#endif // __CONSUMER_HPP__

consumer.cpp implementation file:

#include "consumer.hpp"
#include "a.hpp"

consumer::consumer(const char* const text) : a_(text) {}

void consumer::chat() const {
a_.talk();
}

test - main.cpp file:

#include "consumer.hpp"

int main() {
consumer c("My message");
c.chat();
return 0;
}


UPDATE:




Here is my very contrived working code using the answer below.



a.hpp:
#ifndef A_HPP__
#define A_HPP__

#include

namespace ns1 {


class a {
public:
void set_message(const std::string& msg);
void talk() const;

private:
std::string msg_;
};


} //namespace

#endif //A_HPP__

a.cpp:
#include
#include "a.hpp"

void ns1::a::set_message(const std::string& msg) {
msg_ = msg;

}
void ns1::a::talk() const {
std::cout << msg_ << std::endl;
}

consumer.hpp:
#ifndef CONSUMER_HPP__
#define CONSUMER_HPP__

namespace ns1

{
class a;
}

class consumer
{
public:
consumer(const char* text);
~consumer();
void chat() const;


private:
ns1::a* a_;
};

#endif // CONSUMER_HPP__

consumer.cpp:
#include "a.hpp"
#include "consumer.hpp"


consumer::consumer(const char* text) {
a_ = new ns1::a;
a_->set_message(text);
}
consumer::~consumer() {
delete a_;
}
void consumer::chat() const {
a_->talk();

}


main.cpp:
#include "consumer.hpp"

int main() {
consumer c("My message");
c.chat();
return 0;

}

Answer



To forward declare class type a in a namespace ns1:



namespace ns1
{
class a;
}



To forward declare a type in multiple level of namespaces:



namespace ns1
{
namespace ns2
{
//....
namespace nsN
{

class a;
}
//....
}
}


Your are using a a member of consumer which means it needs concrete type, your forward declaration won't work for this case.


No comments:

Post a Comment

plot explanation - Why did Peaches&#39; mom hang on the tree? - Movies &amp; TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...