Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.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++_Virtual - Fatal编程技术网

C++ 为纯虚函数提供定义

C++ 为纯虚函数提供定义,c++,virtual,C++,Virtual,我是一名Java程序员,对为纯虚拟函数提供定义这一事实感到困惑。在Java中,我习惯于将抽象方法视为我们将在基类中提供定义的方法。但以下代码完全有效: #include <iostream> struct A { virtual ~A() = 0; }; A::~A(){ std::cout << "~A()" << std::endl; } struct B : A { ~B(){ std::cout << "~B()" &l

我是一名Java程序员,对为纯虚拟函数提供定义这一事实感到困惑。在Java中,我习惯于将抽象方法视为我们将在基类中提供定义的方法。但以下代码完全有效:

#include <iostream>

struct A
{
   virtual ~A() = 0;
};

A::~A(){ std::cout << "~A()" << std::endl; }

struct B : A
{
    ~B(){ std::cout << "~B()" << std::endl; }
};

A *a = new B;


int main()
{
    delete a;
}
#包括
结构A
{
虚~A()=0;
};

A::~A(){std::cout您可以定义任何纯虚拟成员函数。但是,即使您定义了
A::foo
,它仍然是纯的,因此
A
B
仍然是抽象类,可能无法实例化。这将导致编译器可能发出的任何错误。

您可以定义任何纯虚拟成员函数成员函数。但是,即使您定义了
A::foo
,它仍然是纯函数,因此
A
B
仍然是抽象类,可能无法实例化。这将是编译器可能发出任何错误的原因。

您显然对代码第二个版本中错误的原因感到困惑

在命名空间范围中为纯虚函数(任何纯虚函数)提供定义没有错。无论它是析构函数还是常规函数,编译器都不会对此抱怨

您在代码的第二个版本中提供的
A::foo
的定义是完全合法的,不会引起编译器的投诉。第二个代码的唯一问题是
B
没有覆盖
foo
。因此
B
仍然是一个抽象类。您正在尝试实例化它

在代码的第一个版本中,从
A
继承的唯一纯函数
B
是析构函数,而
B
中提供了析构函数的非纯定义。因此,
B
不再是抽象类,可以合法实例化

在代码
B
的第二个版本中,继承了
A
的两个纯虚拟函数-析构函数和
foo
。由于没有在
B
中重写
foo
B
仍然是一个抽象类,无法实例化


仅此而已。错误与在命名空间范围中为纯虚拟函数提供主体的能力无关。

您显然对代码第二版本中的错误原因感到困惑

在命名空间范围中为纯虚函数(任何纯虚函数)提供定义没有错。无论它是析构函数还是常规函数,编译器都不会对此抱怨

您在代码的第二个版本中提供的
A::foo
的定义是完全合法的,不会引起编译器的投诉。第二个代码的唯一问题是
B
没有覆盖
foo
。因此
B
仍然是一个抽象类。您正在尝试实例化它

在代码的第一个版本中,从
A
继承的唯一纯函数
B
是析构函数,而
B
中提供了析构函数的非纯定义。因此,
B
不再是抽象类,可以合法实例化

在代码
B
的第二个版本中,继承了
A
的两个纯虚拟函数-析构函数和
foo
。由于没有在
B
中重写
foo
B
仍然是一个抽象类,无法实例化


仅此而已。错误与在命名空间范围中为纯虚拟函数提供主体的能力无关。

当我使用g++4.8.2编译上述程序时,我收到以下消息:

编译器命令:

错误消息:

socc.cc:17:12:错误:无法分配抽象类型“B”的对象
A*A=新的B;
^
socc.cc:12:8:注意:因为以下虚拟函数在“B”中是纯函数:
结构B:A
^
socc.cc:9:6:note:virtualvoid A::foo()
void A::foo(){}
^
make:**[socc]错误1
错误消息的要点是,
B
是一个抽象类型,因为它不提供重写的
void foo();
,该函数在基类中声明为纯虚函数

A::foo()
的定义并不非法。以下程序运行正常:

#include <iostream>

struct A
{
   virtual ~A() = 0;
   virtual void foo() = 0;
};

void A::foo(){ }
A::~A(){ std::cout << "~A()" << std::endl; }

struct B : A
{
    ~B(){ std::cout << "~B()" << std::endl; }
     void foo() {}  // Need this to be able to instantiate B.
};

A *a = new B;

int main()
{
    delete a;
}
#包括
结构A
{
虚~A()=0;
虚拟void foo()=0;
};
void A::foo(){}

A::~A(){std::cout当我使用g++4.8.2编译上述程序时,我得到以下消息:

编译器命令:

错误消息:

socc.cc:17:12:错误:无法分配抽象类型“B”的对象
A*A=新的B;
^
socc.cc:12:8:注意:因为以下虚拟函数在“B”中是纯函数:
结构B:A
^
socc.cc:9:6:note:virtualvoid A::foo()
void A::foo(){}
^
make:**[socc]错误1
错误消息的要点是,
B
是一个抽象类型,因为它不提供重写的
void foo();
,该函数在基类中声明为纯虚函数

A::foo()
的定义并不非法。以下程序运行正常:

#include <iostream>

struct A
{
   virtual ~A() = 0;
   virtual void foo() = 0;
};

void A::foo(){ }
A::~A(){ std::cout << "~A()" << std::endl; }

struct B : A
{
    ~B(){ std::cout << "~B()" << std::endl; }
     void foo() {}  // Need this to be able to instantiate B.
};

A *a = new B;

int main()
{
    delete a;
}
#包括
结构A
{
虚~A()=0;
虚拟void foo()=0;
};
void A::foo(){}

A::~A(){std::cout What?为纯虚函数提供定义是完全合法的。编译器永远不会对此抱怨。第二个代码的唯一问题是您试图实例化抽象类
B
,而不是为纯函数提供定义。@AnT但我在命名空间范围内这样做了。我提供了定义好了,怎么了?在哪里?我在任何地方都看不到
B::foo
的定义。
a::foo#include <iostream>

struct A
{
   virtual ~A() = 0;
   virtual void foo() = 0;
};

void A::foo(){ }
A::~A(){ std::cout << "~A()" << std::endl; }

struct B : A
{
    ~B(){ std::cout << "~B()" << std::endl; }
     void foo() {}  // Need this to be able to instantiate B.
};

A *a = new B;

int main()
{
    delete a;
}