-
Aggregation question
I have a Neighborhood class and a House class. The Neighborhood class includes House.h because it needs to contain a vector<House>. But I also want each House to be able to answer "What neighborhood do you belong to?" I think I need to have a Neighborhood field for each House object, but if I include Neighborhood.h in House, I get an infinite loop of includes. So how could I go about getting House to know about Neighborhood without getting that loop of #includes?
-
You should be using the preprocessor to ensure that nothing gets included more than once.
ie
Code:
#ifndef HOME_HPP
#define HOME_HPP
#include "Home.hpp"
/**
Code here
**/
#endif // HOME_HPP
For a more detailed explanation take a look at the wikipedia page on include guards.
Regards,
cs_student
-
Use a forward declaration and a pointer to a Neighborhood.
-
For an example check the section called Cyclic Dependency here:
C++ Header File Include Patterns
-
Well I have the #ifndef, #define, and #endif lines in both .h files. Maybe I'm using them wrong? Here are the two .h files
Code:
//Neighborhood.h
#include <vector>
using std::vector;
#include <string>
using std::string;
#include "House.h"
#ifndef NEIGHBORHOOD_H
#define NEIGHBRHOOD_H
#pragma once
class Neighborhood
{
public:
Neighborhood(string);
Neighborhood(string, int, int);
Neighborhood(string, int, int, vector<House>&);
Neighborhood(string, vector<House>&);
~Neighborhood(void);
int getLength();
int getWidth();
int getAvailableL();
int getAvailableW();
void setAvailableL(int);
void setAvailableW(int);
vector<House>& getHouseVec();
private:
string name;
int length;
int width;
int availableL;
int availableW;
int houseCount;
vector<House> houses;
};
#endif
Code:
//House.h
#include <iostream>
using std::cout;
using std::endl;
#include <vector>
using std::vector;
#include "HouseItem.h"
#include "Neighborhood.h"
#ifndef HOUSE_H
#define HOUSE_H
#pragma once
class House
{
public:
House(void);
House(int);
House(int, int);
~House(void);
vector<HouseItem>& getItemVec();
int getRooms();
int getLength();
int getWidth();
private:
vector<HouseItem> items;
int rooms;
int length;
int width;
};
#endif
-
Hmm well I just changed House.h to having
Code:
#pragma once
class Neighborhood;
class House
and
Code:
private:
Neighborhood *hood;
which compiles. But why wouldn't the include guards stop the loop between the two .h files?
-
You are not using include guards correctly. Please read the link I posted. It shows proper usage of include guards and proper handling of cyclic dependencies (which include guards will NOT help with). Specifically, the include guards should be the FIRST thing in your header file.
You can forward declare an empty version of a class and reference it in your code as long as:
- You properly define the complete class later on
- You don't use it in a manner where the compiler needs to know how large the class is before it is properly defined
For example:
Code:
This is WRONG:
class Neighborhood;
class House
{
private:
// The compiler would need to know how much space this variable
// takes up, and thus would need to know how large a Neighborhood
// object is.
Neighborhood myNeighborhood;
};
This is OK:
class Neighborhood;
class House
{
private:
// This is ok because the compiler doesn't need to know how big
// a Neighborhood object is. It only needs to know how large a
// pointer is.
Neighborhood *myNeighborhood;
};
-
It is not just about the compiler though. Logically, a house does not contain a neighbourhood, so storing a neighbourhood in a house does not make sense, but allowing a house to have a pointer (or reference) to the neighbourhood that it is in may make sense.