C++ 类定义和原型的放置

C++ 类定义和原型的放置,c++,class,C++,Class,当我创建一个函数时,如果我把原型放在main之上,我可以把它的代码放在main之后。比如说, int myFunction(int a) { return(a); } 会有原型 int myFunction(int a); 在主楼上面 然而,我还不能将其用于类定义 如果我把 class myClass { … }; 在主楼下面 如果我把 class myClass; 在主楼上面。该错误发生在main中使用类的地方,错误是“未知类型名称”。这是C++编译器的一部分,是XCODE的一部分。

当我创建一个函数时,如果我把原型放在main之上,我可以把它的代码放在main之后。比如说,

int myFunction(int a)
{
return(a); 
}
会有原型

int myFunction(int a);
在主楼上面

然而,我还不能将其用于类定义

如果我把

class myClass
{
…
};
在主楼下面

如果我把

class myClass;
在主楼上面。该错误发生在main中使用类的地方,错误是“未知类型名称”。这是C++编译器的一部分,是XCODE的一部分。p>
如果类定义在main下面,我应该在main上面输入什么样的原型?

当您调用一个函数而定义不可用时,编译器不必知道内容,就可以继续评估其余代码(例如:调用站点的堆栈使用情况)。它只需要知道函数的签名就可以确保将正确的参数传递到函数中。编译器完成后,链接器将连接函数调用的实际地址

然而,当您使用一个类时,它必须知道它的细节——不仅仅是它的存在——因为它需要确保堆栈上的正确布局,构造函数需要什么参数,等等


<> P>类的函数的细节当然是正则函数,它只需要签名来工作——它们可以在后面定义。

< P> C++中的函数就像它的调用方的黑盒子一样;他们只需要知道传递什么和返回什么就可以使用它


另一方面,类不能以这种方式使用,因为编译器需要知道为它们分配多少空间、它们的成员类型等。

类定义有点不同,因为它可以包含成员函数原型和定义

如果类定义(通常放在
.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;
}
class-Foo
{
//成员函数原型
void func1();
//类内的成员函数定义
void func2()
{

在某种程度上,函数原型是一个完整类定义的函数等价物,而不是前向声明

因此,前瞻性声明:

class X;
引入名称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
int foo2(X); // X must be defined
这已经完全声明了调用foo(X&)的完整形状和行为。调用站点的代码可以完全编译

涉及定义类的函数原型:

int foo(X&); // X may be forward-declared or defined
int foo2(X); // X must be defined

这充分说明了调用foo2(X)的完整形状和行为,包括将X复制到堆栈上的要求(在使用临时命令调用时将其放置在堆栈中)。调用站点的代码可以完全编译。

在这种情况下,您需要完整的类声明,而不是转发声明。类函数定义仍然可以在
main()之后进行
。感谢大家的回答。这些答案信息丰富,很有帮助。我对所有答案都投了赞成票,并将第一个标记为答案,因为我只能将一个标记为答案。但是,对于未来的读者,我建议所有这些答案都值得一读。它们肯定对我有帮助。