C++:字段的类型不完整
C++: Field has incomplete type
我正在尝试将策略设计模式作为练习来实施。我的 类 非常简单:
1) Fly.cpp
class Fly
{
public:
Fly();
bool fly();
};
class CanFly : public Fly
{
public:
bool fly()
{
return true;
}
};
class CantFly : public Fly
{
public:
bool fly()
{
return false;
}
};
2) Animal.cpp
class Fly;
class Animal
{
Fly myFly;
public:
Animal(Fly f);
void setFly(Fly f);
Fly getFly();
};
Animal::Animal(Fly f)
{
myFly = f;
}
void Animal::setFly(Fly f)
{
myFly = f;
}
Fly Animal::getFly()
{
return myFly;
}
3) Dog.cpp
#include <iostream>
using namespace std;
class Animal;
class Dog : public Animal
{
public:
Dog(Fly f);
};
Dog::Dog(Fly f)
{
setFly(f);
cout << "Dog : " << getFly().fly() << endl;
}
4) Bird.cpp
#include <iostream>
using namespace std;
class Animal;
class Bird : public Animal
{
public:
Bird(Fly f);
};
Bird::Bird(Fly f)
{
setFly(f);
cout << "Bird : " << getFly().fly() << endl;
}
5) AnimalTest.cpp
#include <iostream>
using namespace std;
class Dog;
class Bird;
class CanFly;
class CantFly;
int main()
{
Fly f1 = new CanFly();
Fly f2 = new CantFly();
Bird b(f1);
Dog d(f2);
return 0;
}
我在构建代码时遇到的错误是:
Animal.cpp:5:6: error: field 'myFly' has incomplete type 'Fly'
Fly myFly;
^
谁能帮我看看为什么?
谢谢
将您的 fly.cpp
更改为 fly.h
,在 Animal.cpp
中您应该 #include<fly.h>
或者将您的 myFly
定义为指针 Fly* myFly
。
不完整类型错误意味着编译器看不到 class 的定义,只有声明。
如果您创建 object 或按值传递 object,则需要向编译器提供 class 的定义。您确实创建了 objects 并通过值传递它们,因此您需要包含传递到 cpp 文件中的相关 classes 的定义。
但这不是你真正想做的。
您的意图是采用多态性,因此您需要通过引用或指针传递 objects。
您的动物 class 应该是:
class Animal
{
Fly &myFly;
public:
Animal(Fly &f);
void setFly(Fly &f);
Fly const &getFly();
};
通过这种方式,您可以将 Fly、CanFly 或 CantFly object 中的任何一个传递给 Animal object。
您还需要重新组织您的代码。您需要将 class 个定义分成 header 个文件。例如:
//Animal.h
class Fly; <=== Declaration. OK here.
class Animal
{
Fly &myFly;
public:
Animal(Fly &f);
void setFly(Fly &f);
Fly const &getFly();
};
然后你需要在cpp中包含headers。示例:
#include "Animal.h"
class Dog : public Animal <=== Compiler needs definition of Animal here
{
public:
Dog(Fly f);
};
注意以下定义的区别:
Fly Animal::getFly()
{
return myFly;
}
Returns 一份 object 存储在 myFly 中。
Fly const &Animal::getFly()
{
return myFly;
}
Returns 对 object myFly
的常量引用
此外,也许您根本不需要 Fly, CanFly, CantFly
classes。 类 Bird, Dog
已经 "know" 如果他们能飞或不能飞。当然,你正在做运动,但 Fly、CanFly 等在这里似乎是多余的和做作的。
为了使用 class
,它的 定义 是必需的。像
这样的语句
class Fly;
不是定义,而只是一个声明。已声明的 class 不能使用,但您可以定义指向此类 class.
的指针和引用
因此,为了让您的代码正常工作,您应该将代码拆分为包含 class 定义的 header 文件 (.hpp) 和包含 (non-inline) 在 header 中声明的任何 class 成员的定义。
另外,你好像想使用多态,但是忘了把成员bool Fly::fly()
声明为virtual
。我想你想要的是
// file Fly.hpp
struct Fly
{
virtual bool fly() const = 0;
};
struct CanFly : Fly
{
bool fly()
{ return true; }
};
struct CantFly : Fly
{
bool fly()
{ return false; }
};
然后
// file Animal.hpp
struct Fly; // forward declaration
struct Animal
{
const Fly*const myFly; // use pointer to forwardly declared class
// const data member is public (serves as getter)
bool fly() const;
protected:
Animal(Fly const&f);
// no setter: an Animal cannot change its flying behaviour
};
和
// file Animal.cpp
#include "Fly.hpp"
#include "Animal.hpp"
Animal::Animal(Fly const&f)
: myFly(&f) {}
bool Animal::fly() const
{ return myFly->fly(); } // polymorphic call
不过,我不喜欢这种模式。问题是,为了定义从 Animal
派生的 Bird
或 Dog
,您需要提供对实际 CanFly
和 CantFly
的引用,分别传递给它们基数 Animal
的构造函数。而且,Animal
除了能不能飞之外,没有什么可说的了,为什么还有这个classAnimal
(除了Fly
)?
我正在尝试将策略设计模式作为练习来实施。我的 类 非常简单:
1) Fly.cpp
class Fly
{
public:
Fly();
bool fly();
};
class CanFly : public Fly
{
public:
bool fly()
{
return true;
}
};
class CantFly : public Fly
{
public:
bool fly()
{
return false;
}
};
2) Animal.cpp
class Fly;
class Animal
{
Fly myFly;
public:
Animal(Fly f);
void setFly(Fly f);
Fly getFly();
};
Animal::Animal(Fly f)
{
myFly = f;
}
void Animal::setFly(Fly f)
{
myFly = f;
}
Fly Animal::getFly()
{
return myFly;
}
3) Dog.cpp
#include <iostream>
using namespace std;
class Animal;
class Dog : public Animal
{
public:
Dog(Fly f);
};
Dog::Dog(Fly f)
{
setFly(f);
cout << "Dog : " << getFly().fly() << endl;
}
4) Bird.cpp
#include <iostream>
using namespace std;
class Animal;
class Bird : public Animal
{
public:
Bird(Fly f);
};
Bird::Bird(Fly f)
{
setFly(f);
cout << "Bird : " << getFly().fly() << endl;
}
5) AnimalTest.cpp
#include <iostream>
using namespace std;
class Dog;
class Bird;
class CanFly;
class CantFly;
int main()
{
Fly f1 = new CanFly();
Fly f2 = new CantFly();
Bird b(f1);
Dog d(f2);
return 0;
}
我在构建代码时遇到的错误是:
Animal.cpp:5:6: error: field 'myFly' has incomplete type 'Fly'
Fly myFly;
^
谁能帮我看看为什么?
谢谢
将您的 fly.cpp
更改为 fly.h
,在 Animal.cpp
中您应该 #include<fly.h>
或者将您的 myFly
定义为指针 Fly* myFly
。
不完整类型错误意味着编译器看不到 class 的定义,只有声明。 如果您创建 object 或按值传递 object,则需要向编译器提供 class 的定义。您确实创建了 objects 并通过值传递它们,因此您需要包含传递到 cpp 文件中的相关 classes 的定义。
但这不是你真正想做的。 您的意图是采用多态性,因此您需要通过引用或指针传递 objects。
您的动物 class 应该是:
class Animal
{
Fly &myFly;
public:
Animal(Fly &f);
void setFly(Fly &f);
Fly const &getFly();
};
通过这种方式,您可以将 Fly、CanFly 或 CantFly object 中的任何一个传递给 Animal object。
您还需要重新组织您的代码。您需要将 class 个定义分成 header 个文件。例如:
//Animal.h
class Fly; <=== Declaration. OK here.
class Animal
{
Fly &myFly;
public:
Animal(Fly &f);
void setFly(Fly &f);
Fly const &getFly();
};
然后你需要在cpp中包含headers。示例:
#include "Animal.h"
class Dog : public Animal <=== Compiler needs definition of Animal here
{
public:
Dog(Fly f);
};
注意以下定义的区别:
Fly Animal::getFly()
{
return myFly;
}
Returns 一份 object 存储在 myFly 中。
Fly const &Animal::getFly()
{
return myFly;
}
Returns 对 object myFly
的常量引用此外,也许您根本不需要 Fly, CanFly, CantFly
classes。 类 Bird, Dog
已经 "know" 如果他们能飞或不能飞。当然,你正在做运动,但 Fly、CanFly 等在这里似乎是多余的和做作的。
为了使用 class
,它的 定义 是必需的。像
class Fly;
不是定义,而只是一个声明。已声明的 class 不能使用,但您可以定义指向此类 class.
的指针和引用因此,为了让您的代码正常工作,您应该将代码拆分为包含 class 定义的 header 文件 (.hpp) 和包含 (non-inline) 在 header 中声明的任何 class 成员的定义。
另外,你好像想使用多态,但是忘了把成员bool Fly::fly()
声明为virtual
。我想你想要的是
// file Fly.hpp
struct Fly
{
virtual bool fly() const = 0;
};
struct CanFly : Fly
{
bool fly()
{ return true; }
};
struct CantFly : Fly
{
bool fly()
{ return false; }
};
然后
// file Animal.hpp
struct Fly; // forward declaration
struct Animal
{
const Fly*const myFly; // use pointer to forwardly declared class
// const data member is public (serves as getter)
bool fly() const;
protected:
Animal(Fly const&f);
// no setter: an Animal cannot change its flying behaviour
};
和
// file Animal.cpp
#include "Fly.hpp"
#include "Animal.hpp"
Animal::Animal(Fly const&f)
: myFly(&f) {}
bool Animal::fly() const
{ return myFly->fly(); } // polymorphic call
不过,我不喜欢这种模式。问题是,为了定义从 Animal
派生的 Bird
或 Dog
,您需要提供对实际 CanFly
和 CantFly
的引用,分别传递给它们基数 Animal
的构造函数。而且,Animal
除了能不能飞之外,没有什么可说的了,为什么还有这个classAnimal
(除了Fly
)?