Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么是虚拟&;静态关键字是';不允许在类外声明? 我很想知道为什么C++中不允许有以下内容?_C++_Syntax_Static_Virtual - Fatal编程技术网

为什么是虚拟&;静态关键字是';不允许在类外声明? 我很想知道为什么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中表示继承它将是一个未实现的函数,没有其他类实际实现它的可能性

对于静态,您混淆了它在类上下文外部和内部的含义。如果您希望有一个可以在不需要相应对象的情况下调用的函数,可以将其定义为类的静态函数。如果您希望该函数位于类外部,只需忽略静态,因为该函数不需要恩