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).
Related
I am new to cpp, looking at an existing project.
There are several places in the project where an object is defined in a namespace in some header file and then declared in the same namespace and used in other declarations in some other header file. Example:
MyStruct.hpp:
namespace A { struct MyStruct { int i; }; }
MyClass.hpp:
namespace A { struct MyStruct; }
namespace B {
class MyClass {
private:
void foo(A::MyStruct& s);
};
}
MyClass.cpp:
#include "MyClass.hpp"
#include "MyStruct.hpp"
namespace B {
class MyClass {
void foo(A::MyStruct& s) { /* ... */ }
};
}
I might have expected there to be an #include "MyStruct.hpp" in MyClass.hpp, but that is not the case. I guess when the two header files are isolated there is not yet any relationship between the MyStruct objects in that case. Why does this not create some conflict though when the two headers are loaded together in the implementation file? I cannot, for instance, write int j; int j = 0;. Does the order of the #includes matter? And what might be the motivation for doing this?
What you are seeing is a forward declaration being used.
Since foo() takes a MyStruct by reference, MyClass.hpp doesn't need to know the full declaration of MyStruct in order to declare foo(), it only needs to know that MyStruct exists somewhere. The linker will match them up later.
MyClass.cpp, on the other hand, needs to know the full declaration of MyStruct in order for foo()'s implementation to access the contents of its s parameter. So MyStruct.hpp is used there instead.
This also means that if the contents of MyStruct.hpp are ever modified, any source files using MyClass.hpp don't have to be recompiled since the forward declaration of MyStruct won't change (unless the namespace is changed, that is). Only files that are using MyStruct.hpp will need recompiling, like MyClass.cpp.
MyClass.hpp contains a forward declaration of MyStruct; it’s just telling the compiler that a type named struct MyStruct exists, but not providing any details about what’s in the struct. That’s enough for things like const MyStruct & to compile without syntax errors, but not enough to actually do anything with the struct (since its size and contents are still unknown to the compiler)
As for why someone would do that instead of putting in an #include; it’s a little bit faster to compile, but the main reason would be to avoid cyclic dependencies (eg if MyStruct.h needs to reference MyClass but MyClass.h also needs to reference MyStruct, that would be difficult to achieve using only #include directives)
Forward declarations can hide a dependency, allowing user code to skip necessary recompilation when headers change.
from https://google.github.io/styleguide/cppguide.html#Forward_Declarations
I have learned recently there is some debate over whether to use a forward declare or just include the header within the header itself. At work we forward declare our internal classes (not library code) and include the headers containing those classes in the corresponding .cpp. If the code in the .cpp never uses the class then the include can be skipped entirely; eg it passes a type.
say we have the following code and files
#pragma once
//test.h
class Test{
public:
void foo() const;
};
//test.cpp
#include<iostream>
#include "test.h"
void Test::foo() const
{
std::cout << "test" << std::endl;
}
#pragma once
//worker_function.h
class Test;
void doWork(const Test&);
//worker_function.cpp
#include"worker_function.h"
#include"Test.h"
void doWork(const Test& obj){
obj.foo(); //must include for compilation
}
#pragma once
//myclass.h
class Test;
class MyClass{
public:
void passthrough(const Test& obj);
};
//myclass.cpp
#include "myClass.h"
#include "worker_function.h"
void MyClass::passthrough(const Test& obj){
doWork(obj);
}
MyClass never actually needs to know the size of Test to get to doWork(). So, we don't need an include of Test.h. Only the actual function that does work (doWork) will need to include within its cpp. By using forward declarations, changes to Test.h will not cause any recompilation of MyClass.cpp. But in my view this is a good thing, because it is not a necessary recompilation.
Disclaimer: The google style guide has an example related to void*, but I'm not sure it is related to this bullet point; as it is just an incorrect function call rather than a necessary recompilation. Also, I believe that particular example would be eliminated if the function was defined in the .cpp instead and they included the appropriate classes. Additionally, if it is related to the bullet I have in this question, mitigation of issues related to void* do not sound valid enough to forbid the use of forward declarations entirely.
So, my question is -- is there any concrete example of a case where it will skip a necessary recompilation?
edit:
This is not a duplicate of linked post as that answer only includes a void* response. I stated in this question that I am looking for any other example from the void* given. IMO that is a pretty esoteric issue (hopefully isn't common in modern c++) to completely throw out using forward declarations entirely. It seems to me like creating a rule to never use references, including pass by reference, because class member references can easily yield dangling references via default copy
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.
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.
If I have a class in outside.h like:
class Outside
{
public:
Outside(int count);
GetCount();
}
How can I use it in framework.cpp using the extern keyword, where I need to instantiate the class and call GetCount?
Edit:
#include is not allowed.
Everyone here is a bit too gentle.
There is ABSOLUTELY NO REASON why you would not want to include the .h file.
Go for it and include the file!
Just to clarify. It is impossible to extern the class:
class Outside
{
public:
Outside(int count);
GetCount();
}
But, once you have the class available in framework.cpp, you CAN extern an object of type Outside. You'll need a .cpp file declaring that variable:
#include "outside.h"
Outside outside(5);
And then you can refer to that object in another file via extern (as long as you link in the correct object file when you compile your project):
#include "outside.h"
extern Outside outside;
int current_count = outside.GetCount();
extern is used to say "I KNOW a variable of this type with this name will exist when this program runs, and I want to use it." It works with variables/objects, not classes, structs, unions, typedefs, etc. It's not much different from static objects.
You may be thinking about forward declaring classes to cut down on compile times, but there are restrictions on that (you only get to use the objects as opaque pointers and are not able to call methods on them).
You may also mean to hide the implementation of Outside from users. In order to do that, you're going to want to read up on the PIMPL pattern.
Update
One possibility would be to add a free function to Outside.h (I've also added a namespace):
namespace X {
class Outside {
int count_;
public:
Outside(int count) : count_(count) { }
int GetCount()
{
return count_;
}
};
int GetOutsideCount(Outside* o);
}
Implement that function in a .cpp file. While you're at it, you might as well make the global variable that you intend to extern (note, the variable itself does not need to be a pointer):
#include "outside.h"
namespace X {
int GetOutsideCount(Outside* o)
{
return o->GetCount();
}
}
X::Outside outside(5);
And then do this in your program (note that you cannot call any methods on outside because you did not include outside.h and you don't want to violate the one definition rule by adding a new definition of the class or those methods; but since the definitions are unavailable you'll need to pass pointers to outside around and not outside itself):
namespace X {
class Outside;
int GetOutsideCount(Outside* o);
}
extern X::Outside outside;
int main()
{
int current_count = GetOutsideCount(&outside);
}
I consider this an abomination, to put it mildly. Your program will find the GetOutsideCount function, call it by passing it an Outside*. Outside::GetCount is actually compiled to a normal function that takes a secret Outside object (inside Outside::GetCount that object is referred to via the this pointer), so GetOutsideCount will find that function, and tell it to dereference the Outside* that was passed to GetOutsideCount. I think that's called "going the long way 'round."
But it is what it is.
If you aren't married to using the extern keyword, you can instead go full "let's use C++ like it's C" mode by adding the following two functions in the same way (i.e., via forward declarations and implementing right next to int GetOUtsideCount():
Outside* CreateOutsidePointer(int count)
{
return new Outside(count);
}
void DestroyOutsidePointer(Outside* o)
{
return delete o;
}
I'm more willing to swallow that. It's a lot like the strategy used by the APR.
You don't make classes extern. Just include "outside.h" and create an instance of Outside.
you cant extern the class, but you can extern a function that creates an instance.. In the consumer code:
class Outside;
extern Outside* MakeAnOutside(int count);
extern int GetOutsideCount(Outside* outside);
Then in outside.h:
Outside* MakeAnOutside(int count)
{
return new Outside(count);
}
int GetOutsideCount(Outside* outside)
{
return outside->GetCount();
}
but.. this may not be a good idea..
Include files are for definitions, including class definitions. extern is for variables.
If you don't have the definition of a class in a source file, about the only thing you can do with it is declare it with class Outside; and pass instances around by pointer. You can't actually do anything with the instances, including construction, destruction, or calling member functions like GetCount(). For this, you don't need extern at all; only if you want to refer to a variable in another source file, and that won't let you do anything additional with it.
There is no valid reason not to use #include here. The only alternative is to copy-and-paste the header file into the source file, and that's considerably worse. Anybody who tells you not to use #include does not understand C++, and obviously anybody who thinks extern has any relevance here certainly doesn't.
If at all possible, you should get an experienced C++ developer to help you learn, establish good coding styles, and mentor you in how to develop C++. I suspect you're doing other things that will turn out to be Bad Ideas later on.
If you had a silly requirement that #include is not allowed then you'd have to copy and paste the class declaration into your .cpp file. Need I say that'd be a very bad idea?
What is the reason for this requirement? It pains me to advise you how to do this. If you are trying to avoid long #include paths in your source files, this is a build problem not a source code problem.
You should add directories to the include path with the gcc -I option, or whatever the equivalent is for your compiler.
If you are really, really sure about this, you'd want something like this:
framework.cpp
// FIXME: Should #include "outside.h" but not allowed.
class Outside
{
public:
Outside(int count);
GetCount();
// Omitted
// void SomeUnusedMethod();
};
<code for framework.cpp here>
void UseOutside()
{
Outside o(5);
std::cout << o.GetCount() << std::endl;
}
I would then strongly recommend you leave the declaration as is so it's just straight copy-and-pasted from the header file. But if you want to trim it you can omit any non-virtual methods you don't use. You'll need to keep all variables.
I can only think of one use case where you could 'extern' a class without either #including the header or duplicating the class definition as others have suggested.
If you need to keep pointer to the class but you never dereference it directly, only pass it around, then you can do the following in your file:
class Outside;
class MyClass
{
Outside* pOutside;
void SetOutsidePointer(Outside *p) {pOutside = p;}
Outside* GetOutsidePointer() { return pOutside;}
/* the rest of the stuff */
}
This will only work if you never call pOutside->GetCount() or new Outside in your file.
Put the include for your Outside class in the StdAfx.h or any other headerfile that framework.cpp is already including.
I think you misunderstand the storage classes and one of them is the external.
"Objects and variables declared as extern declare an object that is defined in another translation unit or in an enclosing scope as having external linkage."
So marking extern is for variables not classes defination/declaration
So if you can not include the .h, I recommend you to build the .h and .cpp to be static lib or dll and use in your code
Yikes... we put classes in header files and use #include in order to duplicate class (or other) declarations into multiple cpp files (called compilation units).
If you really can't use #include, you're left with a manual copy, as suggested above, which has the obvious problem of becoming outdated when someone changes the original. That'll completely break your test code with hard to track crashes.
If you insist on going down the path of this manual copy, you do need the entire class declaration. Technically, you could omit certain bits and pieces, but this is a bad idea -- clearly your team doesn't have deep understanding of C++ constructs, so you're likely to make a mistake. Second, the C++ object model is not standardized across compilers. Theoretically even a simple non-virtual method could change the model, breaking your test.
A "long path" is really not a great reason not to include a file directly. But if you really can't, copy the entire header file in where #include would have been -- that's exactly what the C preprocessor is going to do anyway.