I am trying to use forward declarations in header files to reduce the number of #include
used and hence reduce dependencies when users include my header file.
However, I am unable to forward declare where namespaces are used. See example below.
File a.hpp
:
#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__
File a.cpp
:
#include <iostream> #include "a.hpp" using namespace ns1; a::a(const char* const msg) : msg_(msg) {} void a::talk() const { std::cout << msg_ << std::endl; }
File consumer.hpp
:
#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__
Implementation file consumer.cpp
:
#include "consumer.hpp" #include "a.hpp" consumer::consumer(const char* const text) : a_(text) {} void consumer::chat() const { a_.talk(); }
Test file main.cpp
:
#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.
File a.hpp
:
#ifndef A_HPP__ #define A_HPP__ #include <string> namespace ns1 { class a { public: void set_message(const std::string& msg); void talk() const; private: std::string msg_; }; } //namespace #endif //A_HPP__
File a.cpp
:
#include <iostream> #include "a.hpp" void ns1::a::set_message(const std::string& msg) { msg_ = msg; } void ns1::a::talk() const { std::cout << msg_ << std::endl; }
File 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__
File 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(); }
File main.cpp
:
#include "consumer.hpp" int main() { consumer c("My message"); c.chat(); return 0; }
There is no forward declaration of namespace.
In C++, classes and structs can be forward-declared like this: class MyClass; struct MyStruct; In C++, classes can be forward-declared if you only need to use the pointer-to-that-class type (since all object pointers are the same size, and this is what the compiler cares about).
A class can also be declared inside namespace and defined outside namespace using the following syntax: CPP.
Classes are data types. They are an expanded concept of structures, they can contain data members, but they can also contain functions as members whereas a namespace is simply an abstract way of grouping items together. A namespace cannot be created as an object; think of it more as a naming convention.
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.
For nested namespaces, since C++17, you can do
namespace ns1::ns2::nsN { class a; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With