I'm just getting started in C++ and already I have a problem. I'm trying to make a QFile (from QTCore) called brushInput. It's saying "expected a declaration". I've looked it up and it appears to occur from syntax issues but I don't see that in my code. Does it with and without the class.
#include <QtCore>
class Ink
{
QFile *brushInput;
brushInput = new QFile("x:\Development\InkPuppet\brush.raw");
};
You can't have an assignment in a class definition. You could have a default initialization in the class definition in C++11, though:
class Ink
{
QFile* brushInput = new QFile("x:\\Development\\InkPuppet\\brush.raw");
};
However, normally I would expect that the initialization goes into a constructor:
class Ink
{
QFile* brushInput;
public:
Ink(): brushInput(new QFile("x:\\Development\\InkPuppet\\brush.raw")) {}
};
You can't make assignments inside classes, only initializations. Therefore, use the member-initializer list of your class:
class Ink
{
QFile *brushInput;
public:
Ink() : brushInput(new QFile("x:\Development\InkPuppet\brush.raw"));
};
This:
brushInput = new QFile("x:\Development\InkPuppet\brush.raw");
is a statement. Statements (other than declarations) can appear only inside function definitions, not at class or file scope.
Putting the statement inside a function definition (perhaps a constructor) determines when the statement will be executed. If you're thinking it should be executed when the object is created -- well, that's what constructors are for.
As you are clearly new to C++, here a number of things to know to get started:
In C++ there are 2 kind of source files: header files (.h) and source files (.cpp).
Everything in C++ must be both declared and implemented. These are two different things.
The general rule is that the declarations go into the header file, the implementations go into the .cpp file.
In your case:
//ink.h file
#ifndef INK_H //this avoids multiple inclusion
#define INK_H
#include <QtCore>
class QFile; //let the compiler know the QFile is defined elsewhere
class Ink
{
public: //as a rule of thumb,
//always declare the visibility of methods and member variables
Ink(); //constructor
~Ink(); //it is a good practice to always define a destructor
private:
QFile *brushInput;
};
#endif
//.cpp file
#include "ink.h"
//implementation of the constructor
Ink::Ink() :
brushInput(new QFile("x:/Development/InkPuppet/brush.raw"); //you can use forward slashes; Qt will convert to the native path separators
{}
Avoid implementations in header file
As a second rule, avoid implementations in the header file, certainly of constructors and destructors.
Implementations of methods in the header files are known as inline methods (and they have to be marked like that). As a start, avoid them, and try to implement everything in the .cpp file. When you are more familiar with C++, you can start using the 'more advanced' things.
Related
EDIT: Thanks! I'm coming from Java, so it turns out I was just unfamiliar with what free functions are and how they work. I appreciate everyone's answers.
For an assignment, I was given a C++ header file (.h) with a bunch of empty functions that I need to implement in a separate .cpp file without altering the original header fild. However, there's no explicit class or class name ever mentioned in the header file - I was expecting there to be something like
ClassName
{
... functions, etc...
}
but there's nothing, just the member functions. There's also no constructor.
Because there's no class or class name, I'm unsure what syntax to use to implement the member functions in the .cpp file. Where usually I would put something like
returnType ClassName::functionName()
{
...implementation...
}
I'm not sure what to insert in place of the ClassName, since there is no class, or if I need to use a different format entirely. Thanks in advance!
You don't need to insert class name, you just need to correctly wrote the declared function signature in header file:
file.h
#ifndef HEADER_H
#define HEADER_H
void f ();
void g ();
#endif
file.cpp
#include "file.h"
void f ()
{
}
void g ()
{
}
C++ is not as object-oriented as Java or C# and allows free functions - ones that exists outside of any class. It seems that your header declares exactly that.
Use simply
returnType functionName() //defines a function in current namespace, global or other
{
...implementation...
}
However, there's no explicit class or class name ever mentioned in the header file
That's okay; not everything needs to be in a class.
And, if you were under the impression that a header is only for declarations of class-related things (because some courses tend to name them after classes whose definition they contain), that is not true! A header can contain declarations of anything! A class, multiple classes, non-class things, a mix of the above…
there's nothing, just the member functions.
They're not member functions; they're just… functions.
There's also no constructor.
That's okay, too! Only classes need constructors.
Because there's no class or class name, I'm unsure what syntax to use to implement the member functions in the .cpp file.
Functions are simply defined thus:
int foo(…)
{
/* code */
}
…where int is the return type, foo is the name, and … is my placeholder for your arguments (if applicable).
That's it!
There should be a chapter in your textbook about so-called "free functions", probably before classes.
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).
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.
I'm just beginning with C++, so I'm looking some code to learn. I found this code fragment in a Breakout game.
#pragma once
#include "force.hpp"
#include "brick.hpp"
#include <vector>
class Painter;
class Ball;
class Wall
{
public:
enum { ROWS_COUNT = 16,
COLS_COUNT = 8 * 3 };
enum { WIDTH = ROWS_COUNT * Brick::WIDTH,
HEIGHT = COLS_COUNT * Brick::HEIGHT };
Wall();
void draw(Painter &) const;
Force tick(const Ball &);
public:
typedef std::vector<Brick> Bricks;
Bricks bricks_;
};
The only part that I don't understand is the following:
class Painter;
class Ball;
What's mean that two "class [name];"? In the source code there are differents Painter.cpp, Painter.hpp, Ball,hpp, Ball.cpp.
This mean some kind of include?
Those are forward declarations, which can be used to say that a name exists, but no definition of it exists at this time yet, but I want to use the name.
Note that in the class, it only uses pointers and references to Painter and Ball. When using forward declarations, this is completely fine, but if you put in code that depends on knowledge about the internals of the Painter or Ball classes (like calling a function or using a member variable of the class), then you'd have to include the actual class declarations.
For example, notice how the header #includes the brick.hpp header, because the class has an std::vector<Brick> container, that stores copies of Brick objects, and needs to know sizeof(Brick). The header also uses Brick::WIDTH and Brick::HEIGHT.
Another common use case for forward declarations is to fix the circular dependency problem.
That is called a forward declaration.
That just means "Expect there to be a Ball class and Painter class sometime in the future."
What you're looking at is something called forward declaration of types.
The short explanation is that this kind of thing speeds up compilation, because the compiler does not have to look at the header files where these types are declared, you just tell it that the types exist. This is possible as long as you don't need to know exactly the type or use any members. This is a good practice in header files.
This in only something you do in the header files. In .cpp files you need to include the headers where the types are declared, because here you'll most probably use the types and thus must know the real type and what it looks like.
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.