Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

If I create a class like so:

// B.h
#ifndef _B_H_
#define _B_H_

class B
{
private:
    int x;
    int y;
};

#endif // _B_H_

and use it like this:

// main.cpp
#include <iostream>
#include <vector>

class B; // Forward declaration.

class A
{
public:
    A() {
        std::cout << v.size() << std::endl;
    }

private:
    std::vector<B> v;
};

int main()
{
    A a;
}

The compiler fails when compiling main.cpp. Now the solution I know is to #include "B.h", but I'm curious as to why it fails. Neither g++ or cl's error messages were very enlightening in this matter.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
275 views
Welcome To Ask or Share your Answers For Others

1 Answer

In fact your example would build if A's constructor were implemented in a compile unit that knows the type of B.

An std::vector instance has a fixed size, no matter what T is, since it contains, as others said before, only a pointer to T. But the vector's constructor depends on the concrete type. Your example doesn't compile because A() tries to call the vector's ctor, which can't be generated without knowing B. Here's what would work:

A's declaration:

// A.h
#include <vector>

class B; // Forward declaration.

class A
{
public:
    A(); // only declare, don't implement here

private:
    std::vector<B> v;
};

A's implementation:

// A.cpp
#include "A.h"
#include "B.h"

A::A() // this implicitly calls vector<B>'s constructor
{
    std::cout << v.size() << std::endl;
}

Now a user of A needs to know only A, not B:

// main.cpp
#include "A.h"

int main()
{
    A a; // compiles OK
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...