C++ Class Static Members - c++

So I have my header file with static members:
#ifndef PROFILE_MANAGER_H
#define PROFILE_MANAGER_H
#include <map>
#include <vector>
using namespace std;
using std::vector;
namespace Engine
{
class ProfileManager
{
private:
static map<const char*, vector<float>> profiles;
static map<const char*, vector<float>>::iterator it;
static pair<map<const char*, vector<float>>::iterator, bool> ret;
};
}
#endif
And in my cpp file i have the definitions:
#include "ProfileManager.h"
namespace Engine
{
map<const char*, vector<float>> ProfileManager::profiles;
map<const char*, vector<float>>::iterator ProfileManager::it;
pair<map<const char*, vector<float>>::iterator, bool> ProfileManager::ret;
}
The linker always complains about the static members being unresolved externals (LNK2001) even though I have defined them in the cpp file. Any ideas as to why?

These kind of errors usually happen when the linker is not given the obj file that is the result of the compilation of cpp.
Look for ProfileManager.obj in your output directory. If it doesn't exist, there is something wrong. Possibly the cpp file is not compiled as Luchian Grigore suggested. It's also possible that the linker is not given the obj file in the parameters. If you are using visual studio, check that the cpp file is a part of the project. In other environments see the command the linker is invoked with.
If you use Visual Studio, you can open the project properties -> Linker -> Command Line and add /VERBOSE in Additional Option. Then open you output window and recompile the project. (Thank you, Craig for the comment).
One more scenario that could have happened. You included the header file in another project and you tried to build without referencing the project where ProfileManager.cpp was.

Related

Using static library in current project

I'm facing the error when I'm linking an external library and code with the current project. You will understand the problem by this example.
//foo.h
namespace LMS
{
class foo
{
foo(); //implementation in cpp
foo(int dummy) //implemented here
{
//something
}
};
} // namespace LMS
//foo.cpp
#include"foo.h"
namespace LMS
{
foo::foo()
{
//something
}
} // namespace LMS
//externalProgram.h
#include "foo.h"
LMS::foo *ptr;
ptr = new LMS::foo(); //Linking error: LNK 2019
ptr = new LMS::foo(2); //No error
Now the problem is that the external program doesn't know about the foo.cpp and the implementation of class foo methods in it. I'm currently using VS2019 and using two projects in the same solution. I've tried several ways to correct this but it didn't work out. The current way I'm seeing is to implement all the functions in header files.
EDIT: I've already linked the files!!
You should be able to mark your externalProgram project as dependent on the foo project. This will link foo.o in with external program.
Using the UI you will select this in
Project > Project Dependencies : Depends on ...
If that is correct, then the problem is more subtle, sometimes just a simple typo. At this point you want to use the command line tools to break apart the library and confirm the object files, and break apart the object files and confirm the symbols within. A ten year old SO posting discusses using lib.exe to example the library file. The dumpbin tool has a /symbols option that might also be handy for looking at the actual code generated.

Referring to an object from custom library gives error: "pointer to incomplete class type is not allowed"

So in my Visual Studio solution I'm making a library and I have two Visual Studio projects, one for the library and one for the sandbox. In the library I'm trying to use forward declarations to create a class. What I'm simply doing in this example is creating a header file for my class, declaring std::string with the following forward declaration and creating a member pointer with that class.
Library project:
ClassFromLibrary.h
#pragma once
namespace std {
class string;
}
class ClassFromLibrary {
public:
ClassFromLibrary();
~ClassFromLibrary();
std::string* forwardDeclaredString;
};
ClassFromLibrary.cpp
#include "ClassFromLibrary.h"
#include <string>
ClassFromLibrary::ClassFromLibrary()
: forwardDeclaredString(new std::string("Hello, world!"))
{
}
ClassFromLibrary::~ClassFromLibrary()
{
}
Sandbox project
main.cpp
#include <Library/ClassFromLibrary.h>
#include <iostream>
int main()
{
ClassFromLibrary test;
std::cout <<
*test.forwardDeclaredString //Root of the problem
<< std::endl;
std::cin.get();
}
The problem
As I said earlier, the library project compiles perfectly. However, the error which I mentioned in the title shows up when the forward declared member variable is referenced in any file from the sandbox project. I have a larger project where I get the same error, and the reason I want to achieve this is because I am using other external libraries within my library project, and when I create applications with it I don't want to have to put all the library include directories in the project properties, only the one for my library.
Thanks in advance!
You know that putting names in namespace std makes program ill-formed (except for some cases?)? Well, know you know why. The bug you have is a symptom of undefined behavior.
In my test, the way you declared your forward declaration in std is not how it is actually declared in string header. Yet it's a same name, so now you have name conflict (you have it as soon as you include iostream, which includes string. This is what my compiler is telling me when I am try compile your code:
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/basic_string.h:6628:17:
error: reference to 'string' is ambiguous
struct hash<string>
This is different from the error you put in the question, but since the behavior is undefined, anything can happen.

header file include cpp file in visual studio gives compile error

I have my header like:
#include iostream & map
namespace dummy {
const char* some_xxx_name(const char* name);
}
#include myfile.cpp (the following cpp file stated below)
I have my cpp file like:
#include "myfile.h" (the file stated above)
#include <sstream>
#include <cassert>
inline const char* dummy::some_xxx_name(const char* name) {
........
}
They are working fine under my linux environment with makefile, now I am adopting in visual studio environment and get following error:
error C2084: function 'const char *dummy::some_xxx_name(const char *)' already has a body ....(point to the line in the header)
I know the file structure is not good at all for including cpp at header and including header at cpp(or maybe).
want to ask if there is any chance to make it work without updating the code? Not familiary how shall I go forward under windows visual studio environment.

Linker error LNK2019?

I have the following files
file1_moduleA.hpp
file1_moduleA.cpp
sharedFile.hpp
file1_moduleB.cpp
//sharedFile.hpp
extern CustomClass *doSomething(CustomClass *var1, const char *var2);
extern CustomClass *doSomethingElse(const char *var1);
template <class MYCLASS_A>
void myFunction(CustomClass *var1, const char* var2){
assert(somthing);
if (condition){
new (MYCLASS_A);
}
}
//file1_moduleA.cpp
#include "sharedFile.hpp"
// Contains the definitions of doSomething and doSomethingElse among others
//file1_moduleA.hpp
// Other declarations
//file1_moduleB.cpp
#include"sharedFile.hpp"
//...SNIPPETS OF CODE
void someFunction(CustomClass* var1){
doSomething(var1, "FOO");
}
//...
The following are in one Visual Studio Project, Project A:
file1_moduleA.hpp, file1_moduleA.cpp and sharedFile.hpp
The following are in another VS Project, Project B:
file1_moduleB.cpp, file1_moduleB.hpp
Project A compiles and links perfectly, whereas Project B compiles but gives an unresolved symbol for CustomClass *doSomething(CustomClass *var1, const char *var2) at someFunction in file1_moduleB.cpp
I have tried defining the function with and without extern; tried using a separate file for the template in file1_moduleA.hpp; tried inducing dependency between ProjectB and ProjectA in VS, but nothing seems to work. I am unsure why the definition is not being found during linking. ProjectA.lib however, is being created.
Any help in this regard would be appreciated.
if you are using visual studio, and these are different project, then make project B dependent upon project A.
Right click on the solution.
Go to project dependencies.
Choose Project B.
Click Project A (making project B dependent upon Project A)
rebuild.
Did you include shared file in project B?

PCH Warning: header stop cannot be in a macro or #if block - Visual C++ 2010 Express SP1

This is pasted from a website, which presumably was working. I did some googling and found that the issue I have now is a result of Visual C++ 2010 SP1, which I downloaded today, and is now giving me this error:
PCH Warning: header stop cannot be in a macro or #if block.
Hopefully someone will be able to help me with this!
#ifndef APP_STATE_H
#define APP_STATE_H
#include "Framework.h"
class AppState; //this line is giving me the error
//define two classes
#endif
Framework.h:
#ifndef OGRE_FRAMEWORK_H
#define OGRE_FRAMEWORK_H
#include <OgreCamera.h>
#include <OgreEntity.h>
#include <OgreLogManager.h>
#include <OgreOverlay.h>
#include <OgreOverlayElement.h>
#include <OgreOverlayManager.h>
#include <OgreRoot.h>
#include <OgreViewport.h>
#include <OgreSceneManager.h>
#include <OgreRenderWindow.h>
#include <OgreConfigFile.h>
#include <OISEvents.h>
#include <OISInputManager.h>
#include <OISKeyboard.h>
#include <OISMouse.h>
class OgreFramework : public Ogre::Singleton<OgreFramework>,OIS::KeyListener,OIS::MouseListener{
public:
OgreFramework();
~OgreFramework();
bool initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListener = 0, OIS::MouseListener *pMouseListener = 0);
void updateOgre(double timeSinceLastFrame);
//OIS
bool keyPressed(const OIS::KeyEvent &keyEventRef);
bool keyReleased(const OIS::KeyEvent &keyEventRef);
bool mouseMoved(const OIS::MouseEvent &evt);
bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id);
bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id);
Ogre::Root* mRoot;
Ogre::RenderWindow* mRenderWnd;
Ogre::Viewport* mViewport;
Ogre::Log* mLog;
Ogre::Timer* mTimer;
//OIS
OIS::InputManager* mInputMgr;
OIS::Keyboard* mKeyboard;
OIS::Mouse* mMouse;
private:
OgreFramework(const OgreFramework&);
OgreFramework& operator= (const OgreFramework&);
};
#endif
I had the same issue and was looking for a solution. Following worked for me:
Add #pragma once at the start of the file (even before the #ifndef APP_STATE_H header guard)
You probably used a project template to get started and threw away the pre-generated source code files. Those project templates like to turn on precompiled headers because it is such a time-saver. Right-click your project in the Solution Explorer window, Properties, C/C++, Precompiled Headers. Change the "Precompiled Header" setting to "Not Using".
1.Close the Project.
2.Reopen the project,and all ok.
this is my expeirence.
move the #include statements outside the #if #end block
Rebuilding IntelliSense database solves the problem.
Close Visual Studio
Delete [SolutionName].sdf
Delete DllWrappers.opensdf
Delete ipch folder
Open Visual Studio
I had the same problem. My solution was to add a missing ';' at the end of a class definition. Although this does not seem to apply to your problem, others who come here with the same error might find this helpful.
This is probable a day late and a dollar short but I had the same error when I accidentally put my header file in a .cpp file instead of a .h file. I will post it though in case it can help someone.
I just added a referenct to the header file (#include "header.h") and it helped.
I found that my .h file was actually being treated as a .cpp file! Right click on the file in the Solution Explorer > All Configurations > Item Type: C/C++ header
Make sure the item type is not C/C++ compiler or other.
Once you add a .cpp file and have it include the header this error should go away. I've read some where else this is a bug.
I use Visual Studio to edit Linux projects. For me, the issue was present when I include string.h in my precompiled header file. It was caused by lines that have an __asm statement, for example:
__THROW __asm ("memchr") __attribute_pure__ __nonnull ((1));
The solution was to define the following macro under Project Properties, Configuration Properties, C/C++, Preprocessor, Preprocessor Defines:
__asm(x)=
In my case I was wrapping the whole .cpp file inside of #ifdef directive and getting this error.
The issue is, when using precompiled header, your standard precompiled header include needs to be outside of that!
For example:
#include "pch.h" // <- outside of any #if pragma directive
#ifdef EXAMPLE_DIRECTIVE
#include "another_header.h" // <- any other headers can be included inside
class AppState {}; // etc, your code here
#endif
Note that this issue can likely be also caused by some header you're including, which includes PCH header itself. If that's the case, just copy the import of PCH header from that file to the top of the file you're getting the error in, above the #if block.