What must the structure of a class look like if it is defined in a separate namespace?
Which parts belong in the header file and which in the cpp file?
How can I make the class accessible only through this specific namespace?
classname.h
#include <iostream>
namespace N {
class classname {
public:
void classmethod();
}
}
classname.cpp
#include "classname.h"
namespace N {
void classname::classmethod() {
std::cout << "classmethod" << std::endl;
}
}
main.cpp
#include "classname.h"
int main() {
N::classname a;
classname b; // Error!
a.classmethod();
return 0;
}
Related
i have a few headers with namespaces which all follow a certain namepattern
right now they all have a prefix infront of their actual name such as
namespace Xname{//inside name.h
//stuff here
};
namespace Xsomething{//inside something.h
//stuff here
};
now this works pretty good for my usage atm, but my idea is to create one more header that contains a namespace that would collect all the other namespaces so i can access them like so:
#include "mainheader.h"
X::name::stuff
X::something::stuff
this way i would just change the namespace name for new headers in the future like so
X::name::stuff
hello::name::stuff
i cant nest them like this:
namespace x{
namespace something{
//stuff
}
}
You could define the new namespaces inside each other like so
#include <iostream>
namespace Xname{//inside name.h
const int x = 0;
};
namespace Xsomething{//inside something.h
const int y = 1;
};
// Your other header
namespace X {
namespace name = Xname;
namespace something = Xsomething;
}
int main() {
std::cout << X::name::x << "\n";
std::cout << X::something::y << "\n";
}
If I understand you correctly, you can use the using namespace directive for this. Here is an example:
namespace Xname {
struct foo {};
}
namespace X {
namespace name {
using namespace Xname;
}
}
int main()
{
Xname::foo f1; // original
X::name::foo f2; // alternative
}
I created a new project in c++ but i keep getting the same error
Main.cpp
#include <iostream>
#include <string.h>
#include "Computer.cpp"
#include "Computer.h"
using namespace std;
int main()
{
cout << "Hello World!" << endl;
return 0;
}
Computer.h
#ifndef COMPUTER_H_INCLUDED
#define COMPUTER_H_INCLUDED
#include <string>
class Computer
{
public:
std::string marca;
float prezzo;
bool acceso;
Computer();
void Accenditi();
void Spegniti();
void ImpostaMarca(std::string m);
void ImpostaPrezzo(float p);
};
#endif
Computer.cpp
#include "Computer.h"
Computer::Computer()
{
}
void Computer::Accenditi()
{
if(!acceso)
{
acceso = true;
}
else
{
std::cout << "Sono già acceso";
}
}
void Computer::Spegniti()
{
if(acceso)
{
acceso = false;
}
else
{
std::cout << "Sono già spento";
}
}
void Computer::ImpostaMarca(std::string m)
{
marca = m;
}
void Computer::ImpostaPrezzo(float p)
{
prezzo = p;
}
The Problem
i don't understand what's wrong with Computer.cpp, i keep getting "cout is not a member of std". I tryed to add "using namespace std" and i also tryed to add the library #include but i get a new file called "makefile.win". How can i fix this error ?
You need to include iostream header in your Computer.cpp file as such:
include <iostream>
and to make your life easier, you can also add:
using std::cout;
using std::endl;
right at the bottom of your include, that way you don't have to keep adding "std::cout" everytime, you can just use "cout"
Also want to add:
You can remove the include computer.cpp from your main.cpp and just leave the header. The C++ linker will automatically link your computer.h and computer.cpp together since .cpp includes the header, and your main includes the computer.h
Add # include <iostream> at the files that you use std::cout and std::cin.
This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 7 years ago.
Please see my previous post here:
Undefined type error even with forward declaration
I moved the definitions to cpp files and I still face the issue. Any ideas why? My files look like this:
Header1.hpp
#ifndef HEADER1_HPP
#define HEADER1_HPP
namespace sample_ns
{
class sample_class{
public:
static int getNumber();
static void print();
};
}
#endif
Header2.hpp
#ifndef HEADER2_HPP
#define HEADER2_HPP
namespace sample_ns
{
class sample_class2{
public:
sample_class2();
int getNumber2();
};
}
#endif
Source1.cpp
#include "Header1.hpp"
#include "Header2.hpp"
#include "stdafx.h"
#include <iostream>
namespace sample_ns
{
int sample_class::getNumber()
{
sample_class2 obj;
return obj.getNumber2();
}
void sample_class::print()
{
std::cout << "Print utility function" << std::endl;
}
}
Source2.cpp
#include "Header2.hpp"
#include "Header1.hpp"
#include "stdafx.h"
#include <iostream>
namespace sample_ns
{
sample_class2::sample_class2()
{
sample_class::print();
}
int sample_class2::getNumber2()
{
sample_class::print();
return 5;
}
}
In my main I call it as:
std::cout << sample_ns::sample_class::getNumber() << std::endl;
I get 'sample_class2' : undeclared identifier. I tried adding class sample_class2; but that still gives me error
EDIT:
my main file:
#include "stdafx.h"
#include <iostream>
#include "Header1.hpp"
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "hello" << std::endl;
std::cout << sample_ns::sample_class::getNumber() << std::endl;
return 0;
}
The best practice for declaring classes and namespaces in header and cpp files is using structure likes below:
Header1.hpp
#ifndef HEADER1_HPP
#define HEADER1_HPP
#include "Header2.hpp"
#include <iostream>
namespace sample_ns
{
class sample_class{
public:
static int getNumber();
static void print();
};
}
#endif
Source1.cpp
#include "Header1.hpp"
namespace sample_ns
{
int sample_class::getNumber()
{
sample_class2 obj;
return obj.getNumber2();
}
void sample_class::print()
{
std::cout << "Print utility function" << std::endl;
}
}
So by including in header files and using ifndef you become sure that circular dependencies will not occure.
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;
}
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;
}
Apart to forward-declare the class from within its namespace (as #billz says), remember to either use (prepend) that namespace when referring to the forward-declared class, or add a using clause:
// B.h
namespace Y { class A; } // full declaration of
// class A elsewhere
namespace X {
using Y::A; // <------------- [!]
class B {
A* a; // Y::A
};
}
Ref: Namespaces and Forward Class Declarations
Please excuse me but I didn't know to give a name to the title in a short way.
Why do I need to declare an overloaded operator inside the header to make it work in this example:
HEAD.H
#pragma once
namespace test {
class A {
public:
A() : x(0) {}
int x;
};
A& operator++(A& obj); //this is my question
}
HEAD.CPP
#include "head.h"
namespace test {
A& operator++(A& obj) {
++obj.x;
return obj;
}
}
MAIN.CPP
#include <iostream>
#include "head.h"
using namespace std;
using namespace test;
int main() {
A object;
++object; //this won't work if we delete declaration in a header
return 0;
}
operator++ is defined and declared in a namespace inside "head.cpp" so why do I need to declare it one more time in a header?
Thank you.
The CPP files are compiled independently of each other, and they only see the header files they've included (which are in fact textually added to the source code of the CPP before compilation). As such you'll use the header file to inform the compiler that a function exists with that signature (be it an operator overload).
Then the output from your CPP files is put together by the linker, which is when you'd find out if for instance you had declared a function in a header file but never taken the trouble to implement it.
Simple example with namespaces:
#include <iostream>
namespace test{
int f() { return 42; }
int g() { return -1; }
}
namespace other{
int f() { return 1024; }
}
using namespace other;
int main(){
//error: 'g' was not declared in this scope
//std::cout << g() << std::endl;
std::cout << test::f() << std::endl; //42
std::cout << f() << std::endl; //1024
return 0;
}