Advertisement

[C++] Declare private class variable without #include

Started by October 30, 2018 11:32 PM
6 comments, last by RoamBlade 6 years, 3 months ago

Hi,

if I understood correctly, class variables (members?) are declared in a header file. However when I declare them in a header file I have to #include the variable types in the Header as well and then other libraries using my library start complaining about not knowing the included header file and this goes on and on.

All I want is a private per object variable, not to be accessed by anyone outside the scope. It seems ridiculous that other classes have to know variable types of variables they can't even Access (private:).

Thanks

Advertisement

Firstly, you can forward declare types, when you're dealing with pointer-type members or reference type members.

Secondly, because you can forward declare types, an often followed pattern is the "pImpl" pattern, where in your header looks like the following:


class Impl;

class Bar {
  private:
    std::shared_ptr<Impl> m_pImpl;
};

And your .cpp file is where you actually define the `Impl` type.

 

Lastly, you shouldn't be having issues with your #includes missing as you describe. If you are, then there's something else wrong with your project setup.

 

@Rutin

Please don't perceive this as rude behaviour because it is not intended to be but I am going to ignore your answer since KulSeran understood my question. So I am going with that and hope others understand as well.

@KulSeran

I looked at these forward declarations but it doesn't compile. It says different things like "Syntaxerror ';' missing".


#pragma once
#define API __declspec(dllexport)

namespace map {
	namespace example {
		class Vertex;
	}
}

namespace robot {
	class API Robot
	{
	public:
		Robot();
		~Robot();
	private:
		Vertex* lastRobotPose;
		Network* network;
	};
}

Vertex is in namespace map::example::Vertex

You need to write out `map::example::Vertex * lastRobotPos`, if Vertex is in a different namespace from where you're trying to use it.

However, for your robot, it seems strange that you'd want to have a pointer there.  `#include "Vertex.h"` or whatever the correct header is seems more appropriate here.

 

 

@IceCave no worries! I miss understood what you where asking for. I thought it was just about basic includes as you posted prior that you were just learning C++ in the other thread I helped with. Glad you figured it out. I took out my reply.

Programmer and 3D Artist

Advertisement

Great! It's overcomplicated but works like a charm!

The reason for making it a pointer and using a Forward declaration is because Vector is a class of giant (scientific) library consisting of over 50 dlls and probably thousands of Header files. When you want to use this library the Compiler starts asking Questions About Header files up to the 100th including iteration. Binding them all in and Setting everything up correctly is a pain in the…. Would be easier if there was a simple interface that only lets you make binding in one dll, a bunch of Header files you actually Need and then just drop the other dlls in. And this is exactly what I am trying to do Right now, simplify the interface.

Have you tried cross platform design writing, for example:

robot.h


namespace robot {
	struct private_data;
	class API robot {
    public:
    	void doSomething();
	private:
		private_data* p;
	};
}

robot.cpp


#include <vertex.h>
  
namespace robot {
  struct private_data {
    map::example::Vertex* v;
    // etc.
  };
}

void robot::doSomething() {
  private_data.v-> ...;
}

This was all private data is hidden from users of robot::robot, and only the actual implementation understands what the private_data is.

In addition, now you can have win32_robot.cpp, and linux_robot.cpp each with their own definition of private_data.

Last thing, about a simple interface to bind is usually done by declaring the function pointers and loading the dll's you are interested in manually.

Like,


#define GAME_UPDATE_AND_RENDER(name) void name(GameMemory* gameMemory, user_input::GameInput* input, float frameTime)
typedef GAME_UPDATE_AND_RENDER(Game_UpdateAndRender);

HMODULE hMdl = LoadLibraryA(TempDLLName);
Game_UpdateAndRender* UpdateAndRender;
if (hMdl) {
	UpdateAndRender = (Game_UpdateAndRender *) GetProcAddress(hMdl, "GameUpdateAndRender");
}

// or for OpenGl
typedef void WINAPI gl_uniform_matrix_4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
gl_uniform_matrix_4fv *glUniformMatrix4fv;
glUniformMatrix4fv = (gl_uniform_matrix_4fv *)wglGetProcAddress("glUniformMatrix4fv");

 

This topic is closed to new replies.

Advertisement