为什么是虚拟&;静态关键字是';不允许在类外声明? 我很想知道为什么C++中不允许有以下内容?
第一个计划:为什么是虚拟&;静态关键字是';不允许在类外声明? 我很想知道为什么C++中不允许有以下内容?,c++,syntax,static,virtual,C++,Syntax,Static,Virtual,第一个计划: #include <iostream> class Test { public: int myfun(); } virtual int Test::myfun() { return 0; } int main() { } #包括 课堂测试{ 公众: int myfun(); } 虚拟int测试::myfun() {返回0;} int main() { } [错误]“虚拟”类外声明 第二个方案: #include <iostream>
#include <iostream>
class Test {
public:
int myfun();
}
virtual int Test::myfun()
{ return 0; }
int main()
{ }
#包括
课堂测试{
公众:
int myfun();
}
虚拟int测试::myfun()
{返回0;}
int main()
{ }
[错误]“虚拟”类外声明
第二个方案:
#include <iostream>
class Test {
public:
int myfun();
};
static int myfun() {
std::cout<<"This program contains an error\n";
return 0;
}
int main() {
Test::myfun();
return 0;
}
#包括
课堂测试{
公众:
int myfun();
};
静态int-myfun(){
std::cout您希望通过在类外声明这个来创建一个函数virtual
。但是,想想将使用您的类的其他代码。您很可能只包含#您的测试
类的头,它将只包含类测试
块,而不是实现。因此ile编译该代码编译器不会知道函数是虚拟的
。但是,它需要知道,因为它需要为虚拟的
和非虚拟的
函数生成不同的调用代码
更详细地说,假设一个比您的示例更高级的程序。按照您的建议,它将包含几个编译单元,并按如下方式组织(为了清楚起见,省略了ifdef
):
//Test.h
课堂测试{
公众:
int myfun();
};
//Test.cpp
#包括“Test.h”
虚拟int测试::myfunc(){返回0;}
//其他.cpp
int foo(Test&Test){return Test.myfunc();}//您希望通过在类外声明来创建一个函数virtual
。但是,考虑一下将使用您的类的其他代码。您很可能只包含测试
类的头,它将只包含类测试
块,而不包含实现编译该代码时,编译器不会知道函数是虚拟的
。但是,它需要知道,因为它需要为虚拟的
和非虚拟的
函数生成不同的调用代码
更详细地说,假设一个比您的示例更高级的程序。按照您的建议,它将包含几个编译单元,并按如下方式组织(为了清楚起见,省略了ifdef
):
//Test.h
课堂测试{
公众:
int myfun();
};
//Test.cpp
#包括“Test.h”
虚拟int测试::myfunc(){返回0;}
//其他.cpp
int-foo(Test&Test){return Test.myfunc();}/virtual
与多态性有关,这就是为什么它只允许在类内部使用。static
允许在类外部使用,并使全局函数“私有”。程序的问题是,myfun()
类中的Test
不是静态的,您必须创建一个Test实例来调用此方法
int main()
{
Test test;
test.myfun(); // works
return 0;
}
myfun()的静态版本与类无关,不能像这样调用:Test::myfunc()
(因为,正如我所说,它与Test无关)。您可以这样调用它:
int main()
{
myfun(); // global function, has nothing to do with any classes
return 0;
}
virtual
与多态性有关,这就是为什么它只允许在类内使用。static
允许在类外使用,并使全局函数“私有”。程序的问题是,myfun()
类中的Test
不是静态的,您必须创建一个Test实例来调用此方法
int main()
{
Test test;
test.myfun(); // works
return 0;
}
myfun()的静态版本与类无关,不能像这样调用:Test::myfunc()
(因为,正如我所说,它与Test无关)。您可以这样调用它:
int main()
{
myfun(); // global function, has nothing to do with any classes
return 0;
}
修饰符必须位于函数声明上,否则就不可能仅在声明中调用函数
因为它们必须在声明中,所以将它们也放在定义中是多余的。没有特别好的理由不允许它们(只要它们与声明匹配),但也没有特别好的理由允许使用它们。修饰符必须在函数声明上,否则就不可能只在声明中调用函数
因为它们必须在声明中,所以将它们也放在定义中是多余的。没有特别好的理由不允许它们(只要它们与声明匹配),但也没有特别好的理由允许它们。编译器编译一个源文件(“翻译单元”)每次。如果你要声明一个类
#include "Test.h"
class SpecialTest : public Test {
int myfun();
};
编译器只查看“Test.h”中的内容,而不查看“Test.cpp”中的内容。因此,如果允许您仅在.cpp文件中创建myfun()
virtual
,编译器不必查看“Test.cpp”就无法正确编译“SpecialTest”编译器编译一个源文件(“翻译单元”)每次。如果你要声明一个类
#include "Test.h"
class SpecialTest : public Test {
int myfun();
};
编译器只查看“Test.h”中的内容,而不查看“Test.cpp”中的内容。因此,如果允许您仅在.cpp文件中创建myfun()
virtual
,编译器不必查看“Test.cpp”就无法正确编译“SpecialTest”如注释中所示,虚拟仅在上下文ob类中有意义。回想一下,虚拟方法是一个没有实现的函数,将其留给从定义虚拟方法的类继承的其他类。但是,如果虚拟定义在类之外,如何在此cas中表示继承它将是一个未实现的函数,没有其他类实际实现它的可能性
对于静态,您混淆了它在类上下文外部和内部的含义。如果您希望有一个可以在不需要相应对象的情况下调用的函数,可以将其定义为类的静态函数。如果您希望该函数位于类外部,只需忽略静态,因为该函数不需要恩