AKV
AKV

Reputation: 455

c++ extern class does not name a type

I'm trying to declare a class object as extern but am getting the below error:

g++ a1.cpp -std=c++11

In file included from b1.h:5:0,
                 from a1.cpp:2:
c1.h:6:8: error: ‘b1’ does not name a type
 extern b1 obj_b1;
        ^

I have looked in Issue declaring extern class object and '[Class name]' does not name a type in C++

and I THINK I am following the steps mentioned there. But couldn't find what's the issue.

Files are :

a1.cpp

#include<iostream>
#include "b1.h"

b1 obj_b1;


int main(){

    //access object from class B
    std::cout << " test  " << std::endl;
    std::cout << " obj_b1 value is   " << obj_b1.value << std::endl;
    obj_b1.value = 6;
    return 0;
}

b1.h

#ifndef CLASS_B1
#define CLASS_B1

#include "c1.h"

class b1{
public:
    int value=5;
    int print_value();
};
#endif

b1.cpp

#include <iostream>
#include "b1.h"

int b1::print_value(){
        std::cout << "value in b1 is " << value << std::endl;
}

c1.h

#ifndef CLASS_C1
#define CLASS_C1
#include "b1.h" // this is an attempt to fix issue, but didnt work

extern b1 obj_b1; // Is there a better place to declare this ?

class c1 {
private: 
    int c1_value=10;
    int c1_print_value();
};
#endif

c1.cpp

#include<iostream>
#include "c1.h"

int c1::c1_print_value()
{
    std::cout << "in c1 , value is " << c1_value << std::endl;
    std::cout << " obj_b1.value is " << obj_b1.value << std::endl;
    return 0;
}

I can not understand why the compiler complains about b1, when I have added b1.h just above the extern declaration. Can someone help to solve the issue ?

Upvotes: 0

Views: 1026

Answers (1)

HAL9000
HAL9000

Reputation: 2188

b1.h includes c1.h, and c1.h includes b1.h. This is is a mess. By using the #indef/#define combo, you have prevented an infinite recursion, but it is still a mess.

obj_b1 doesn't have anything to do with class c1, so remove extern b1 obj_b1; from c1.h.

Now c1.h doesn't depend on anything in b1.h, so you can remove #include "b1.h" from c1.h. An for similar reason, you should remove #include "c2.h" from b1.h.

On the other hand c2.cpp does depend on obj_b1 (assuming obj1.name is a typo, and should be obj_b1.name), so you should put extern b1 obj_b1; in b1.h and #include "b1.h" in c2.cpp.

For some extra cleanup, move b1 obj_b1; from a1.cpp to b1.cpp

Upvotes: 2

Related Questions