当我创建一个函数时,如果我将原型放在main之上,我可以在main之后输入代码。例如,
int myFunction(int a)
{
return(a);
}
会有原型..
int myFunction(int a);
以上主要内容。
但是,我无法将其用于类定义。
如果我放......
class myClass
{
…
};
低于主要,
如果我放
,我会收到错误class myClass;
以上主要内容。在main中使用类的错误发生,错误是“未知类型名称”。那就是作为Xcode一部分的c ++编译器。
如果类定义低于main,我应该在main上面输入什么样的原型?
答案 0 :(得分:4)
当您调用函数并且定义不可用时,编译器不必知道内容以继续评估其余代码(例如:调用站点的堆栈使用情况)。它只需要知道函数的签名,以确保将正确的参数传递给函数。编译完成后,链接器将连接函数调用的实际地址。
但是当你使用类时,它必须知道它的细节 - 不仅仅是它存在 - 因为它需要确保堆栈上的正确布局,构造函数需要什么参数等等
课程详情'函数当然像常规函数 - 它只需要签名即可使用 - 它们可以在以后定义。
答案 1 :(得分:4)
C ++中的函数就像是调用者的黑盒子;他们只需要知道传递什么以及为了使用它而返回的内容。
另一方面,类不能以这种方式使用,因为编译器需要知道为它们分配多少空间,它们的成员类型等等。
答案 2 :(得分:2)
类定义稍有不同,因为它可以包含成员函数原型和定义。
如果您的班级定义(通常放在.h
文件中)位于同一个文件中,那么您希望它位于main()
之上。可以在main()
之后定义在类定义之外定义的函数,如下所示。
class Foo
{
// member function prototype
void func1();
//member function definition inside class
void func2()
{
std::cout << "Hello from func2" << std::endl;
}
};
int main()
{
foo instance;
instance.func1();
instance.func2();
return 1;
}
void Foo::func1()
{
std::cout << "Hello from func1" << std::endl;
}
答案 3 :(得分:2)
在某种程度上,函数原型是完整类定义的函数等价物,而不是前向声明。
所以,转发声明:
class X;
引入名称X并通知编译器它是一个类。看到这个之后,编译器将允许您保存并传输引用和指向X的引用,但不能创建或复制它的值(实例),所以:
void foo(X&); // is allowed (because it deals in references), but
void foo(X); // is not (it deals in copies of an X)
类定义:
class X { ... };
完全定义了X的界面和存储要求。在此之后,编译器将允许您使用X执行任何您喜欢的操作。这就是类定义通常会进入头文件的原因。
涉及前向声明类的函数原型:
int foo(X&); // X may be forward-declared or defined
这完全宣告了调用foo(X&amp;)的完整形状和行为。呼叫站点的代码可以完全编译。
涉及已定义类的函数原型:
int foo2(X); // X must be defined
这已经完全声明了调用foo2(X)的完整形状和行为,包括将X复制到堆栈上的要求(用于在临时调用时将其置于那里)。呼叫站点的代码可以完全编译。