Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
//TreeBox.h
#pragma once
#include "ListBox.h"
struct ItemInfo
{
std::string _fileName;
std::string _childName;
std::string _time;
std::string _format;
std::string _size;
std::string _nodeKey;
};
class TreeBox
{
...
}
//ListBox.h
class
{
public:
std::vector<ItemInfo> _itemList; //compile error
}
I wanna use std::vector in "ListBox.h" from using struct in "TreeBox.h"
but it was compile error allocator C2903
how do I use that?
You need not to include ListBox.h in TreeBox.h
Always follow practice of including standard libraries first and then the .h files
#pragma once
#include <vector>
#include <string>
class ListBox;
struct ItemInfo
{
std::string _fileName;
std::string _childName;
std::string _time;
std::string _format;
std::string _size;
std::string _nodeKey;
};
class TreeBox
{
};
#pragma once
#include <initializer_list>
#include "TreeBox.h"
class ListBox
{
public:
std::vector <ItemInfo> _itemList;
private:
};
Simply add #include <vector> to the top of your header to include the STL vector. #including a file header at the top of a file allows you to access the objects defined in that header.
You're including ListBox.h at the beginning of TreeBox.h. Specifically, you're including it before the part of TreeBox.h that defines ItemInfo.
So, you're trying to define a vector<ItemInfo> before the compiler knows what an ItemInfo might be, and it doesn't like that.
Rearrange your definitions so by the time the compiler sees the code trying to create a vector<ItemInfo>, it has already seen the definition of ItemInfo (and be sure you've included <vector>, in case you don't have that yet).
So with things in the correct order, you'd have something like this:
#include <vector> // First, tell the compiler about `vector`
class ItemInfo { // ...and `ItemInfo`
// ...
};
class ListBox {
std::vector<ItemInfo> itemList; // *Then* we can use `vector` and `ItemInfo`
// ...
};
If you want some of the pieces of that to be in separate headers that you #include, that's fine--but you still need to get the definitions in the right order.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am trying to iterate through an array to objects to set different attributes of those objects. The attributes of my objects may change over time.
My code as a simplified example:
// MyClass.h
class MyClass
{
/* class definitions */
};
extern MyClass object;
// MyClass.cpp
#include MyClass.h
/* Constructors, Destructors, Functions */
// main.cpp
void reload_objects();
int main()
{
MyClass object[20];
reload_objects();
{
void reload_objects();
{
for (int i = 0; i < 20; i++){
object[i].setProperties(/*args*/);
}
}
I am getting an error error: No match for 'operator[]' (operand types are ‘MyClass’ and ‘int’). If I move the for loop into main it compiles and runs fine.
What is causing this error?
Would it be easier or in some way better to use std::vector<MyClass> object(20) in some way?
There are several mistakes in your given code snippet. You can correct them as i have shown below. I have added comments wherever i have made changes.
MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
// MyClass.h
class MyClass
{
/* class definitions */
public:
MyClass() = default;
};
extern MyClass object[20]; //declare object as an array
#endif
MyClass.cpp
// MyClass.cpp
#include "MyClass.h"
/* Constructors, Destructors, Functions */
main.cpp
#include <iostream>
#include "MyClass.h"
MyClass object[20]; // define object here instead of inside main()
void reload_objects(); // reload_objects() doesnt take any argument by looking at its call and definiton
int main()
{
// MyClass object[20]; //don't define object here
reload_objects();
}
void reload_objects() //you had a semicolon here so i removed it
{
for (int i = 0; i < 20; i++){
object[i].setProperties(/*args*/);
;
}
}
Also don't forget to add the definition and declaration of your other member functions like setProperties in the above example for it to work. These are some of the changes that i made:
You should declare object as an array of size 20 inside MyClass.h.
Define object outside of main() inside main.cpp as i did in my example.
Declare the function reload_objects() with no arguments in main.cpp.
This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 2 years ago.
So, I know that there are many questions on stack overflow out there that are trying to handle circular dependencies. But none of those could really answer my question, if it is possible to have two classes know each other, and, more importantly, access information from each other. So, basically, I have read that you could use forward decleration, but with forward decleration, I couldn't access any fields. Maybe I should also add that I am really new to C++.But enough talking, let's get to an example:
Let's say we have a class called Scene and a class called EntityBase, which are defined as following:
EntityBase.h
#pragma once
#include <string>
#include "Scene.h"
class EntityBase
{
public:
std::string entityId;
Scene scene;
EntityBase(std::string entityId);
/*
This method will be called when this object is added to the scene
*/
void onAddedToScene(Scene* scene);
/*
This method will be called when this object is removed from the scene
*/
void onRemovedFromScene(Scene* scene);
};
Scene.h
#pragma once
#include <vector>
#include <string>
#include "EntityBase.h"
class Scene
{
public:
std::vector<EntityBase> entities;
std::string name;
Scene(std::string name);
void addToScene(EntityBase& entityBase);
};
The question arises,
How can I print out the name of Scene(and use every method of Scene) while EntityBase can fully access Scene too?
So, I'd really appreciate if you'd tell how to do this, because I will probably need to access every field and/or method later.
Since the C++17 standard you don't need the full EntityBase class definition for the Scene class, only a forward declaration:
#pragma once
#include <vector>
#include <string>
class EntityBase; // Forward declaration
class Scene
{
public:
std::vector<EntityBase> entities;
std::string name;
Scene(std::string name);
void addToScene(EntityBase& entityBase);
};
You of course need to include EntityBase.h anywhere where the entities vector is used, most notable in the Scene.cpp source file.
Since EntityBase is using an actual instance of Scene you can't do the same with that class and the EntityBase.h header file. Here you must include the Scene.h header file.
If you build targeting an older C++ standard (C++14 or earlier) then you must have the full definition of the EntityBase class for the vector.
As a possible workaround either make entities a vector of pointers to EntityBase; Or make EntityBase::scene a pointer and use forward declaration in the EntityBase.h header file instead. Or a combination of both.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
Note: I have searched thoroughly on SO and the solutions posted for other's with similar questions are not working for me here.
I am writing my own custom 'string-like' class in C++, and am encoutering the following errors when compiling:
./PyString.h:8:11: error: out-of-line declaration of 'PyString' does
not match any declaration in 'PyString' PyString::PyString (char*);
^
./PyString.h:9:11: error: definition of implicitly declared destructor PyString::~PyString (void);
pystring.cpp:4:7: error: redefinition of 'PyString' class PyString {
As for the first and second errors, moving around the destructor into the class definition itself in the cpp file did not work.
As for the third error, I can't seem to fix it - I'm not redefining the class!
Here is pystring.h:
#ifndef PYSTRING_INCLUDED
#define PYSTRING_INCLUDED
class PyString {
char* string;
};
PyString::PyString (char*);
PyString::~PyString (void);
#endif
Here is pystring.cpp:
#include "PyString.h"
#define NULL 0
class PyString {
char* string = NULL;
public:
PyString(char inString) {
string = new char[inString];
};
~PyString(void) {
delete string;
};
};
For reference, here is the compile output as a screenshot:
Any help is greatly appreciated.
You're defining your class PyString in your header AND in your cpp file, and also, a function definition doesn't need a ; at it's end.
And... your function prototypes needs to be in your class declaration in your header :
pystring.h
class PyString {
public: //ALWAYS indicate what is public/private/protected in your class
PyString (char* inString);
~PyString (); // Don't put void when there's no parameter
private: // All attributes are private
char* string;
};
pystring.cpp
#include "PyString.h"
PyString::PyString(char* inString) {
string = inString; // Avoid using new unless you're forced to
}
PyString::~PyString() {
}
Oh yes you are! pystring.h contains
class PyString {
char* string;
};
which is a class declaration. The declarations PyString::PyString (char*);
and PyString::~PyString (void); need to be inside that declaration.
But you have something similar in pystring.cpp, specifying additional functions, and defining some of them. That's what your compiler is telling you.
Normally, you fully define a class in a header (i.e. all members, and the declaration of the member functions), and implement the member functions of that class in a source file.
The moral of the story here: you can't really learn C++ by trial and error. Get a good book!
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I have written a class:
CVerifObj.hpp:
#pragma once
#include <vector>
class VerifObj
{
private:
cv::Mat m_image;
PointVector m_plateContour;
std::string m_imageName;
public:
VerifObj(const fs::path& imgNameIn);
~VerifObj();
cv::Mat getImage() const;
std::string getImageName() const;
PointVector getPlateContour() const;
};
typedef std::vector< VerifObj > VerifObjVector;
That has implementation and that is used as a type of another function in another class that includes its header:
MyCls.hpp:
#pragma once
#include "CVerifObj.hpp"
class MyCls
{
public:
MyCls();
~MyCls();
static VerifObjVector foo(); // error is here
};
The problem I get is that it is not recognized:
/home/sop/proj/CMyCls.hpp:52:2: error: ‘VerifObjVector’ does not name a type
I have added it in the CMake file too. Why is this happening?
You haven't included the std::vector definition:
#include <vector>
You're probably including MyCls.hpp in CVerifObj.hpp, directly or indirectly, which leads to a circular include. This can cause issues (undefined types).
Remove circular includes by using forward declarations.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Take the following example:
// base.h
#include <string>
struct base
{
virtual ~base() = default;
virtual void do_something(const std::string& arg) const = 0;
};
// derived.h
struct derived : base
{
void do_something(const std::string& arg) const
{
//...
}
};
In this example should derived.h include the string header?
I fully agree with the principle of including what you use but in this case base.h has to include string and if the interface changes to not use string (and the include <string> is accordingly removed from base.h) then the interface will break highlighting anyways.
If the interface changes not to include string, your derived do_something will have to change as well. If you need in the derived.h independently of the interface (e.g. due to details unrelated to interface but present in the implementation) - in this case yes, it's valid and probably preferable to include <string> there as well.
I take the approach of always includeing anything I need for that file. I then don't have to go around hunting through headers and untangling webs of dependencies when I'm missing a symbol somewhere. Include guards mean that this is cheap.
But it's completely up to you. If you want to omit it, to make derived.cpp shorter, and add it in at a later date if the need arises, that's fine too.
There's simply no "right" answer.
You can include "base.h". Don't think too much.The less code you write,the better your code is.
#include "base.h"
struct derived :public base
{
void do_something(const std::string& arg) const
{
//...
}
};