code organization in c++ - c++

I have a class that spans over two files. It is declared in a declare.h file and defined in define.cpp file.
define.h
class A{
public: int a;
void func(){ a = some_other_func(); }
A();
};
define.cpp
A::A(){
a =0;
}
The overall idea is to initialize a variable in constructor before using it in an inline function. But the constructor definition and function definition are in different files. Is there any issue with this?

There is absolutely no issue with the declaration/definition separation, provided declare.h is included in define.cpp. But the usulal practice is for implementation files to have the same name as declaration files, bar the suffix. So your case could be A.h and A.cpp.
However, there is an issue with the initialization of member variable a itself. You may want to initialize int a in the constructor initialization list:
A::A() : a(0) {}
In your code, it is not being initialized at all . You are creating and initializing a local variable called a a local variable in the body of the constructor. Presumably that is not what you intended.

You need to #include "declare.h" in define.cpp and then write constructor as A::A() : a(0){}.

Though in general this is no technical issue with this. You should adopt the convention that the .h files are interfaces to your code and as such they should only have what is needed for some other code to call yours.

Related

Using objects that are declared in different files across the whole project

I have a C++ project that has multiple files.
File A.h
#ifndef A_H
#define A_H
class A
{
void somefunctionA();
};
A a;
#endif
File B.h
#ifndef B_H
#define B_H
class B
{
void somefunctionB();
};
B b;
#endif
I want to use object a in class B and object b in class A
So basically I want to use variables a and b anywhere in the program.
main.cpp
#include "A.h"
#include "B.h"
...
But there is a conflict. Object "a" isn't seen in class B.
What can be done in this situation and is there a better approach?
You can declare a class anywhere, like in an unrelated header file.
For example:
#ifndef B_H
#define B_H
// Declaration of class A
class A;
extern A a;
class B
{
void somefunctionB();
};
extern B b;
#endif
Now in the implementation of e.g. B::somefunctionB you can use the variable a without seeing the definition of the variable. You do need the definition of the A class though.
A declaration is basically you telling the compiler that something exists, what type it is and what name it have. It's like function prototypes, you declare that somewhere there is a definition of a function, but after the function prototype declaration you can call the function without having seen the function definition (implementation).
A definition, on the other hand, is what tells the compiler (and later the linker) that "this is it". The definition of a variable is not only telling the compiler that the variable exists, but also instructs the compiler to reserve space for the variable in the resulting executable program. A definition of a function is the actual implementation of of the function, where you have the code inside the function.
Incidentally, if a variable or function haven't been declared then the compiler sees the definition of the variable or function, then the definition is also the declaration.
If, as you state, you have all code for the classes inline in the class definition you will have a problem using the global variables with only a class declaration, you need the complete class definition. But if you use class A in class B and the other way around, you have a circular dependency that is hard to break: Class A needs class B to work, but class B needs class A to work.
The easiest solution to break this circular dependency is to put the code from class A that uses class B in a separate source file, and the same for the code in class B that uses class A. This way the header files will not need to include each other giving you the circular dependency, and the source files can include both header files without problems.
Use the singleton pattern for implementing classes that should have only a single global instance:
class A
{
public:
static A& instance()
{
static A instance_;
return instance_;
}
virtual ~A() {}
private:
A() {} // prevent direct instantiation
A(const A&); // prevent copy construction
A& operator=(const A&); // prevent assignment
};
Then use A::instance() wherever you need to interact with the object instance.
Of course this pattern should be used sparingly. Make sure that you really need a global object before creating one and that there is no other way which will give you the same functionality.
Please note that this pattern is not suitable for global objects that depend on each other as the order of static initialization is undefined.

Why can I declare constructor out of the class

Consider this link. See this code:
class MyClass
{
public:
MyClass();
~MyClass();
private:
int _a;
};
MyClass::MyClass()
{
}
MyClass::~MyClass()
{
}
We can declare constructor out of the class.
Why can I declare constructor out of the class and why we should do this?
You cannot declare constructor out of the class. You are talking about constructor definition.
class MyClass
{
public:
MyClass(); // declaration
};
MyClass::MyClass() // definition
{
}
You should read this.
The main reason why you should define your constructor outside the class is for readability. It is clearer to declare your class in the Header file and define it in the source file. You can apply this rule any members of your class.
A little quote from the standard :
12.1 Constructors
struct S {
S(); // declares the constructor
};
S::S() { } // defines the constructor
You cannot. This is the constructor declaration, which has to be in the class definition:
// MyClass definition, possibly in .h file
class MyClass
{
public:
MyClass(); // default constructor declaration
...
};
and this is the constructor's definition
// MyClass default constructor definition, possibly in .cpp file
MyClass::MyClass() { }
What you are referring to is the constructor's definition. You can define it outside of the class definition to allow you to de-couple one from the other. Usually this means you put the class definition in a header file, to be included by client code, and the constructor definition (as well as other class member function definitions) in an implementation file that gets compiled. This way, users of your code have no compile time dependency on said definitions.
The main reason for defining the constructor (or any member function) outside of the class declaration is so that you can have a header file and an implementation file. This makes your code clearer to read and allows you to distrbute the interface to your class (the header file) without providing the implementation details.
You can not declare a constructor or anything part of the class, outside it, but you can define
It's a common c++ programming practise of using 2 files for 1 class
For example,
ClassG.h
class ClassG
{
public:
ClassG();
~ClassG();
void anyfunc(int anyarg);
private:
int anydata;
};
ClassG.cpp
#include"ClassG.h"
ClassG::ClassG()
{
//something
}
ClassG::~ClassG()
{
//something
}
void ClassG::anyfunc(int anyarg)
{
//something
}
General Syntax
While declaring, inside .h file type returntype methodname(args_if_any);
While defining in a .cpp file type returntype ClassName::methodname(args_if_any){}
First of all, you have your terminology confused, you need to read What is the difference between a definition and a declaration?. You can not declare a constructor outside of a class but you can define it outside of a class.
So on to the questions as you meant them:
Why can I define a constructor out of the class
Basically the standard has this to say about member functions in section 9.3.2:
A member function may be defined (8.4) in its class definition, in which case it is an inline member function (7.1.2), or it may be defined outside of its class definition if it has already been declared but not defined in its class definition.
So the standard says this is ok, next question:
why we should do this?
It makes your code cleaner and easier to digest, you can separate your declarations into header files and your implementation into source files. This previous thread Why have header files and .cpp files in C++? goes into this topic in more detail.
Yes, you can define the constructor inside the class no matter that whether you are
using .h file or .cpp file. Actually the main difference between both the file is,
header file never compile it only use for checking syntax during compilation of .cpp
file.
Method that you define inside the class by default inline function. If you define one
constructor inside the class it's fine but, if you required to define more than one
constructor then 2 problem occur
Problem 1:
As we know that, when you call inline function it will paste code in called
function that increase the code size and required more memory.
Problem 2:
Reduce the readability of code.

Strange code segment from c++

Reading code from other posts, I'm seeing something like this.
struct Foo {
Foo() : mem(0) {}
int mem;
};
What does mem(0) {} does in this case, especially regarding the curly brackets? I have never seen this before and have no idea where else I would find out about this. I know that mem(0), would intialize mem to 0, but why the {}?
Thanks.
Since Foo() is the class' constructor, it must have a body, even if the member variable mem is initialized outside of it.
That's why, in your example, the constructor has an empty body:
Foo() : mem(0)
{
// 'mem' is already initialized, but a body is still required.
}
It defines the constructor of the class. The part after the colon is the initialization list, in which the mem member is initialized to zero using a constructor call.
Compare:
int a(0);
int b = 0;
These two do the same, but the former is more in line with how object construction typically looks in C++.
int c++ you can define your method implementation in .h file
class MyClass
{
public:
MyClass(){
.....
}
void doSomething(){
.....
}
~MyClass(){
.....
}
};
Usually it used in templates implementation. Also you could use this method of class declaration in case you would like to avoid libraries linking and you prefer to give to user all your code so he can include your file without linking any lib file to his project.

C++ - .h and .cpp

If I have a .h file that contains the following for example:
class A
{
...
}
Notice that there is no customized constructor here.
Now, in the .cpp file, can I write the following:
A
{
...
}
In other words, is it ok not to use a constructor after the class name as follows?
A::A()
{
...
}
Thanks.
If your question is whether or not you can use A{} to define a constructor, no, you need to use A::A(){...} syntax for the constructor if you are defining it in the cpp file.
If you are asking if you don't need a constructor, no, you don't necessarily need one, the compiler will supply you with a default.
I should say that if you are doing the constructor in the class definition you can use A(){...}, such as
class A
{
public:
A(){}
};
I believe the answer to your question is "No". But it's kind of a confusing question. The syntax you propose for the contents of the .cpp file is demonstrably uncompilable.
is it ok not to use a constructor after the class name
As classes get longer and more complicated, mixing the definition and the implementation details makes the class harder to manage and work with.
Traditionally, the class definition is put in a header file of the same name as the class, and the member functions defined outside of the class are put in a .cpp file of the same name as the class.
No. Once you've defined class A like that, the compiler expects A to start one of
A MyObject;
A MyOtherObject = { /* initial values */ }; // C style since there's no ctor
A MyFunction();
A MyFunction() { return MyObject; }
or perhaps a variation like
A* MyPointer;
A& MyReferemce = MyObject;
As you see, the compiler expects you declare something after A. But you have A {. That's just not right: you started a declaration, but you never named what you're declaring.
Yes You Can.If i understood your question correctly.
HEADER FILE
#include &lt iostream&gt
using namespace std;
class A{
public:
A();
void func();
};
CPP FILE
#include "h.hpp"
using namespace std;
A::A(){cout &lt&lt "Constructor" &lt&lt endl;}
int main(){
A a;
return 0;
}

Is it possible to add an object of a class in the class header?

I was wondering if there is a way to put objects of a class in a header?
For example:
class MyClass {
} object;
If I made an object there and then include the header in more than one source file, I get an error of multiply defined symbols found. I am new so don't understand fully everything.
Also, I want to do something like object.function() inside of a different function which is a member of a different class how can I do that?
Assuming you want a single object, in the header file just declare the object:
extern blabla object;
and then in one source file define it:
blabla object;
As for calling a method on an object from a different class, that is perfectly fine as long as the method is public.
class foo
{
public:
void public_method();
private:
void private_method();
};
void some_other_class::method(foo &f)
{
f.public_method(); // this is fine
f.private_method(); // this is not okay, private_method can only be called from
// within foo
}
There's also a third visibility (protected), which comes into play once you start dealing with inheritance.
You can find ways to do it (see the other answers), but just don't do it. As you said, you are new to C++, so better learn the good practices, and when you need global objects - create them in the source (cpp) file.
Besides it, try to avoid using global objects at all, and define your objects inside the classes or functions.
It's not a good practice to put definitions in header files as this would result to the error you encountered. Although there are ways to get around this (extern, header guard), it should be avoided as much as possible. Just remember, put declarations in header files, definitions in source files.
About your second question note you can also call a static method using the :: operator and the class name (without an instance) :
void AnOtherClass::method()
{
TheFirstClass::static_method();
}
You could also make a use of the singleton pattern, if that fits your need in this case.
For your second question. You can always make a class object as a (private) member variable of the class you want to call object.function() from.
For example:
// File a.h, includeguards etc. left out for clarity
class A {
public:
void func();
};
// File b.h
#include "a.h"
class B {
public:
void func();
private:
A object;
};
// File b.c
#include "b.h"
void B::func()
{
object.func();
}
Hope that helps.