Shouldn't line 15 in CBottle.h give you a error. Isnt it a incomplete type, because it is only a forward declaration and the compiler doesnt know what CCarton contains?
It does give you that error if you change it to this:
Well how can you access any fields of the bottle class if you only forward declare it? One of the headers included in your CCarton.cpp file must be including Cbottle.h. This is then not included in just the header file, so the constructor can't access any of the fields in bottle.
Shouldn't line 15 in CBottle.h give you a error. Isnt it a incomplete type, because it is only a forward declaration and the compiler doesnt know what CCarton contains?
Yes, it's incomplete. No, it shouldn't give you an error, because you're only declaring a method, and declaring reference to the class. Nowhere in CBottle.h are you doing anything that requires the compiler to know the definition of CCarton, so it's OK to use an incomplete type.
This is why it's often a good thing to use references and/or pointers in your class definition headers - it allows you to avoid header file dependencies, which can slow down compilation time a lot when you're working on a project of a significant size.
But why does it give me that error if I add my constructor back in? My constructor gives the error because it needs to access dimensions of the aBottle class which is why, but doesn't the CCarton do the same? Accessing my constructor?
But why does it give me that error if I add my constructor back in?
That should be obvious - in your second version of CCarton.h, the compiler does need to know the definition of CBottle, because you're accessing the members of CBottle.
Yes. If you use the second version, then the constructor is accessing members of CBottle, so you need to have CBottle already defined (by including the header file).
That code is in CBottle, and isnt it accessing CCarton, which is not defined, only declared.
I don't think so. It's just declaring that there exists a method called CCarton::Carton, that takes a reference to a CBottle.
I know why the second wont work, but if I use the second, the constructor in CCarton gives me a error as well this line in CBottle.
My question is why this line is also giving a error with that constructor but none if it the constructor is in the cpp?
Sorry, I'm genuinely unclear what you're trying to say here. Can you post the versions of the files (header and cpp files) that are giving you the errors? And, as always, give us the errors too?
#pragma once;
class CCarton; // Forward declaration
class CBottle
{
public:
CBottle(double height, double diameter)
{
m_Height = height;
m_Diameter = diameter;
}
double m_Height; // Bottle height
double m_Diameter; // Bottle diameter
// Let the carton constructor in
friend CCarton::CCarton(const CBottle& aBottle);
};
Main:
1 2 3 4 5 6 7 8 9 10 11 12
#include "CCarton.h"
#include "CBottle.h"
#include <iostream>
usingnamespace std;
int main ()
{
CBottle nib;
return 0;
}
Output:
1>------ Build started: Project: Tests, Configuration: Debug Win32 ------
1> Main.cpp
1>c:\users\anmol\documents\visual studio 2012\projects\c++ book\code from book\chapter 09\ex9_05\ccarton.h(9): error C2027: use of undefined type 'CBottle'
1> c:\users\anmol\documents\visual studio 2012\projects\c++ book\code from book\chapter 09\ex9_05\ccarton.h(2) : see declaration of 'CBottle'
1>c:\users\anmol\documents\visual studio 2012\projects\c++ book\code from book\chapter 09\ex9_05\ccarton.h(9): error C2228: left of '.m_Height' must have class/struct/union
1>c:\users\anmol\documents\visual studio 2012\projects\c++ book\code from book\chapter 09\ex9_05\ccarton.h(10): error C2027: use of undefined type 'CBottle'
1> c:\users\anmol\documents\visual studio 2012\projects\c++ book\code from book\chapter 09\ex9_05\ccarton.h(2) : see declaration of 'CBottle'
1>c:\users\anmol\documents\visual studio 2012\projects\c++ book\code from book\chapter 09\ex9_05\ccarton.h(10): error C2228: left of '.m_Diameter' must have class/struct/union
1>c:\users\anmol\documents\visual studio 2012\projects\c++ book\code from book\chapter 09\ex9_05\ccarton.h(11): error C2027: use of undefined type 'CBottle'
1> c:\users\anmol\documents\visual studio 2012\projects\c++ book\code from book\chapter 09\ex9_05\ccarton.h(2) : see declaration of 'CBottle'
1>c:\users\anmol\documents\visual studio 2012\projects\c++ book\code from book\chapter 09\ex9_05\ccarton.h(11): error C2228: left of '.m_Diameter' must have class/struct/union
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Look here is what my book says on the ones that do not compile:
"You might think that this will compile correctly, but there is a problem. The CCarton class definition refers to the CBottle class, and the CBottle class with the friend function added refers to the CCarton class, so you have a cyclic dependency here. You can put a forward declaration of the CCarton class in the CBottle class, and vice versa, but this still won’t allow the classes to compile. The problem is with the CCarton class constructor. This appears within the CCarton class definition and the compiler cannot compile this function without having first compiled the CBottle class. On the other hand, it can’t compile the CBottle class without having compiled the CCarton class. The only way to resolve this is to put the CCarton constructor definition in a .cpp file. The header file holding the CCarton class iinition will be:"
See it says that line 15 refers to thing so it has to be compiled but I dont understand why, its only a declaration, so why?
And it should continue to give the error because even after when it still does not have access to the definition...
Based on all this I do not think that line 15 should matter much.
Another way to fix it by simplying adding CCarton.h to CBottle.h.
If you dont understand my question just ask, I really need this answered. Thanks!