Inheritance Conundrum

So I've got a little bit of a problem with a program I'm working on. I've got two classes: class A and class B. Class A has a header file defined like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma once
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include <string>
#include <vector>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int size;
bool scan;
std::vector<std::vector<std::string>> vec;
class A{
//functions here
};
#endif 

Inside class B's header file, class B is defined as such:
1
2
3
4
class B : public A {
public:
    //functions
}

The problem is though, the only way for class B to actually know that class A even exists is if I include class A's header file. However, I have global variables defined in that header file and I will get "variable __ already defined" errors if I try to include it, for obvious reasons.
A simple fix would be to simply move the variables and the WndProc function inside class A. However, I cannot do that because WndProc must either be a global function or be static. When I make it a global function, I have to make the variables global as well so it can see them.
When I put WndProc inside the class as a member function and declare it as static, I get a bunch of errors. What should I do?
Last edited on
Can you improve the example a bit? It's not quite showing the error, even assuming "myClass" is actually "B". What you have currently are a bunch of declarations, not definitions. So if you had an error, it would mention things being redeclared, not redefined.

Edit: nevermind, sorry! for simple types like "int" I did indeed get a "redefinition: previously declared here" error ;D

Can maybe show that it will be defined somewhere else with "extern":

A.h
extern int size;

main.cpp
1
2
3
4
#include "A.h"
int size = 45;

int main() { return 0; }
Last edited on
My apologies. "myClass" is actually class "A". The declarations are the variable declarations, which are the main part of the problem. Here's an example of an error I get: "LNK2005: "bool scan" (?scan@@3_NA) already defined in file.obj"
And I get a weird error when I try to declare it with "extern". It says "invalid storage class for a class member"
> It says "invalid storage class for a class member"
¿did you put extern inside the class?
we shouldn't have to guess your errors, post the code that causes the problem.
Yes I moved the variables back inside the class. The thing is, I want them to be defined inside A.cpp. If I set them as extern inside A.h (outside of the class this time), won't it just assume they are being defined outside of A (when they really aren't)? I need to #include A.h inside B.h so it knows about the A class, but I don't want it to know about any of the global variables that are defined there. After marking them as extern and moving them back outside of the class again, I get "unresolved externals" errors for the variables that I marked as extern.
Maybe something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// wndproc.h -----------------------------------------------------

#pragma once
#include <windows.h>
extern int size;     // extern indicates that the variables exist in another compilation unit
extern bool scan;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


// wndproc.cpp ---------------------------------------------------

#include "wndproc.h"

int size = 123;     // only actually define the variables in one compilation unit (.cpp file)
bool scan = true;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM) {
    ...
}


// a.h -----------------------------------------------------------

#pragma once

class A {
public:
    void func();
};


// a.cpp  --------------------------------------------------------

#include "wndproc.h"
#include "a.h"

void func() {
    ...
}


// b.h -----------------------------------------------------------

#pragma once

#include "a.h"

class B: public A {
public:
    void another_func();
};


// b.cpp ---------------------------------------------------------

#include "b.h"

...

Last edited on
I'll try that. I don't like how the variables are being defined inside a class I'm only going to be using once though. I think the best solution would be to have them as member variables within A.h and put WndProc in there as well but declare it as static.
However, of course I now get errors like "a nonstatic member reference must be relative to a specific object" since a static function is trying to access non-static members. I read that I can get around this by using pointers but I'm not really sure how to do that.
Here's part of the WndProc function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
static LRESULT CALLBACK mainClass::WndProc(HWND hwnd, UINT msg,
	WPARAM wParam, LPARAM lParam) {
	bool checked = true;
	HWND text, button, selection1, selection2;
	//hwnd is parent window

	switch (msg) {

	case WM_CREATE: {
		text = CreateWindow("STATIC", "Please select options from below:", WS_VISIBLE | WS_CHILD, 20, 20, 300, 25, hwnd, NULL, NULL, NULL);
case WM_COMMAND: {
		int i = wParam;
		if (i == 0) //LOWORD(wParam)
		{
			for (int j = 0; j != vectorSize; j++)
			{
				if (IsDlgButtonChecked(hwnd, j + 1) == true)
				{
					check.push_back(j);//member variable
					
				}
			}
                 }
case WM_DESTROY: {

		PostQuitMessage(0);
		break;
	}
	}
	return DefWindowProcW(hwnd, msg, wParam, lParam);
}

It gets called by this function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void A::select(vector<string>& return)
{
	HINSTANCE hInstance = GetModuleHandle(NULL); //NULL = the current process
	WNDCLASSW wc = { 0 };
	MSG  msg;

	wc.lpszClassName = L"Selection1";
	wc.hInstance = hInstance;
	wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 255));
	wc.lpfnWndProc = WndProc;
	wc.hCursor = LoadCursor(0, IDC_ARROW);
	wc.style = CS_DBLCLKS;

	RegisterClassW(&wc);
	CreateWindowW(wc.lpszClassName, L"Selection",
		WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, &ret);

	while (GetMessage(&msg, NULL, 0, 0)) {

		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
 //work is done here with "ret"
}
I need to #include A.h inside B.h so it knows about the A class, but I don't want it to know about any of the global variables that are defined there.

It sounds like you want these variables to be accessible to WndProc and class A, but not to class B.

METHOD 1: Make them file scope variables and define WndProc and class A's methods in one file:

A.h:
1
2
3
4
5
6
7
8
#pragma once
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
class A{
//function declarations go here, but not the definitions (code)
   void method1();   // for example
};
#endif  


B.h
1
2
3
4
5
#include "A.h"
class B : public A {
public:
    //functions
}


somefile.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <string>
#include <vector>
#include "A.h"
static int size;
static bool scan;
static std::vector<std::vector<std::string>> vec;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM)
{
    // code accesses size, scan and vec.
}

void A::method1()
{
    // code that accesses size, scan and vec.
}


METHOD 2: Make them global but only declare them where you need access:
A.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include <string>
#include <vector>
class A{
    void method1() {
        extern  int size;
        extern bool scan;
        extern std::vector<std::vector<std::string>> vec;
        // code that accesses size, scan and vec.
    }
};
#endif  


main.cpp:
1
2
3
4
5
6
7
int size;
bool scan;
std::vector<std::vector<std::string>> vec;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM)
{
    // code accesses size, scan and vec.
}
Thank you for the suggestions!
Topic archived. No new replies allowed.