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 < iostream>
using namespace std;
class A{
public:
A();
void func();
};
CPP FILE
#include "h.hpp"
using namespace std;
A::A(){cout << "Constructor" << endl;}
int main(){
A a;
return 0;
}
Related
I have a small problem with C++ vector.
In my .H file i have
class MyClass{
private:
std::vector<myObject> test;
public:
MyClass();
add(myObject object);
}
In my .CPP file
MyClass::MyClass(){
std::vector<myObject> test;
}
MyClass::add(myObject object){
//here is the problem. Netbeans does even giving me quick cast this method i need to write it myself and it throws an error.
test.push_back(object);
}
I am using NetBeans 8 and it says "Unable to resolve identfier push_back and I don't know why. I'm pretty new to C++ and done some research but it seems like I can't find the answer.
My goal is to have .H file and i initialize vector in .CPP and then i want to have separate function like add to push my objects to this class that contains a vector. Something like a list where you can add your objects.
Thank You for help.
EDIT:
And yes I include vector at the top.
EDIT:
Thats the code
#include <vector>
class MyClass{
private:
int a;
std::vector<int> test;
public:
MyClass();
void add(int n);
};
MyClass::MyClass(){
}
void MyClass::add(int m){
//unable to resolve identifier push_back
test.push_back(m);
}
int main() {
MyClass a();
//request for member add in a which is of non class type
a.add(1);
}
You forgot to add return type for add method.
Try this in H:
void add(myObject object);
And this in CPP:
void MyClass::add(myObject object){
int main() {
MyClass a();
//request for member add in a which is of non class type
a.add(1);
}
//request for member add in a which is of non class type
Because a is not a MyClass object. In order to make it one, you need to construct it like this:
MyClass a{};
or simply like this:
MyClass a;
Otherwise it is treated as function declaration. Here it is, compiled with no errors https://ideone.com/y7fQXo
Based on your "full" code (which doesn't show the dividing line between .h and .cpp, but I'm taking you at your word that the code is complete), it's clear there is only one #include, at the top of the .h code. I'm assuming the .cpp code begins with the line MyClass::MyClass(){, which means it has no includes. Thus, it doesn't have any of the information from your header, and by extension, has none of the information from <vector>.
#include <vector> is needed in your .h (because you used vector in the class definition), but you also need to #include "myclass.h" (or whatever you named your header file) in myclass.cpp (or whatever you named the source file).
Without it, while the compiler is compiling the .cpp file, it's just stumbling in the dark. It has no definition for MyClass as a whole, and therefore has no idea test is a member of type vector<int>. Not knowing what test is (and for that matter, not knowing what a vector<int> is), it can't resolve any methods on it.
To make this work, you need to include your .h in your .cpp so the compiler has the declarations to interpret your method definitions. If your header is named myclass.h, add:
#include "myclass.h"
to the top of your .cpp. For good measure, it might also make sense to explicitly #include <vector> in the source file as well; yes, it will get it by side-effect via including the header, but it's largely harmless to double-include standard library headers (protected against double-inclusion via include guards), and it makes it clear what standard library components you're relying on (useful to maintainers).
I'm converting my old c++ program into OOP and as things grow bigger I'm splitting it per class in .h and .cpp files. The first class compiled nicely into an object file. But my second class is dependant on that first class and now I run into problems. Here my very simplified "all in a single file" code that works:
class A {
public:
void amethod(int) {
....code....
}
};
A a_obj; //object creation
class B {
public
void bmethod(void) {
a_obj.amethod(int);
}
};
B b_obj; //object creation
main() {
b_obj.bmethod();
}
After deviding the code over different files my .h files look like:
//file A.h:
class A {
public:
void amethod(int);
};
//file B.h
#include "A.h"
class B {
public
void bmethod(void);
};
In the implementation of class B there is the call to a_obj.amethod() and even I understand that g++ has no way to know that a_obj is an object of class A as I did not even include the a_obj object creating anywhere in the code.
How to solve this ? Is it something simple that I need to put the object creation somewhere in my .h or .cpp file (note that lots of other classes are using the same amethod()). I can not make everything static as I also have classes with multiple objects (in fact the same way of working is all over the program). Or is this way of working completely wrong (which would explain why I can not find any solution for this).
Is suggest you put more efforts in defining your interfaces.
If class B needs an instance of A to work, use parameters to pass an A:
class B {
public
void bmethod(A & a_obj) {
a_obj.amethod(int);
}
};
main() {
A a_obj;
B b_obj;
b_obj.bmethod(a_obj);
}
The problem is that your original code uses global data (i.e. the declarations of a_obj and b_obj are global). Globals are generally a bad idea because they can cause several problems. The 'proper' OOP way to do it would be to instantiate those objects in main(), and pass them to whatever other objects need to access them. You could pass references, pointers, or copies, depending on your needs.
With that said, if you really want to continue doing it with global data, then you can use an extern declaration. In each *.cpp file where you access a_obj, include this:
extern A a_obj;
That basically tells the compiler that there is an object with that name, but it exists somewhere else. I really don't recommend this approach if you're serious about learning OOP though.
I guess you are planning to use a_obj as global variable in other implementation file (.cpp).
So in header file B.h type extern reference to this instance.
extern A a_obj;
This declaration should help compile your B.cpp file. And ask actual instance a_obj during linking.
I didnt try this code, but telling by my experience and my practice(way) of coding. Hope this solution helps, else am sorry.
First, in order to call A::amethod() class B needs the full definition of class A and its amethod(). So you need to #include A.h before B.h in your .cpp files.
Next, if you address concrete a_obj object, you need to specify what that object is in order to link properly. In you first variant it was global object, so if it is what intended you can write: in A.cpp:
A a_obj;
in B.cpp:
extern a_obj;
// here you can call a_obj methods
But if these classes are so related that one calls methods of another, and also as I catched you need several objects of A and B, consider to connect these classes through inheritance:
class B : public A {
public:
void bMethod(int n) {
aMethod(n); // base class method call
}
// ...
or through delegation:
class B {
A m_A;
public:
void bMethod(int n) {
m_A.aMethod(n);
}
// ...
As mentioned earlier the way
void bMethod(A& a) {
a.aMethod();
}
will work, but the language has built-in means to express classes relationships.
How to implement is more design question, you can read more about this in Stroustrup 3rd edition, '24.3.5 Use Relationships'.
In C++ you can also pass a pointer to a member function of one class into the member function of another class to call a method from completely unrelated class (say, some callback), you can use boost::function and boost::bind for this. But it is advanced technique.
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.
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.
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.