Error only virtual member functions can be marked override

What version of gRPC and what language are you using? Language: C++ GRPC version: git commit 80e834a What operating system (Linux, Windows,...) and version? Mac OS X 10.15.5 ClearLinux with Linux k...

What version of gRPC and what language are you using?

Language: C++
GRPC version: git commit 80e834a

What operating system (Linux, Windows,…) and version?

  1. Mac OS X 10.15.5
  2. ClearLinux with Linux kernel 5.6.17-960 x86_64

What runtime / compiler are you using (e.g. python version or version of gcc)

  1. clang 11.0.3
  2. gcc 10.1.1

What did you do?

Tried to build an example grpc service based on the proto definitions here:
C++ quickstart

I included GRPC in a Bazel WORKSPACE file as follows:

grpc_version = "80e834abab5dff45e16e9a1e3b98f20eae5f91ad"

git_repository(
    name = "com_github_grpc_grpc",
    commit = grpc_version,
    remote = "https://github.com/grpc/grpc.git",
)

load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")

grpc_deps()

load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")

grpc_extra_deps()

Bazel configuration follows:

build --verbose_failures
build --cxxopt='-std=c++17'
build --cxxopt='-Wall'
build --cxxopt='-Wextra'
build --cxxopt='-Wpedantic'
build --cxxopt='-Werror=unused'
build --cxxopt='-Werror=uninitialized'
build --compilation_mode=dbg
build --strip=never

What did you expect to see?

A complete build without errors.

What did you see instead?

INFO: Analyzed 104 targets (0 packages loaded, 0 targets configured).
INFO: Found 104 targets...
...
Use --sandbox_debug to see verbose messages from the sandbox
In file included from external/com_github_grpc_grpc/src/compiler/cpp_plugin.cc:21:
In file included from external/com_github_grpc_grpc/src/compiler/cpp_plugin.h:29:
In file included from external/com_github_grpc_grpc/src/compiler/protobuf_plugin.h:24:
In file included from external/com_github_grpc_grpc/src/compiler/python_generator_helpers.h:29:
external/com_github_grpc_grpc/src/compiler/python_generator.h:47:41: error: only virtual member functions can be marked 'override'
  uint64_t GetSupportedFeatures() const override;
                                        ^~~~~~~~
In file included from external/com_github_grpc_grpc/src/compiler/cpp_plugin.cc:21:
external/com_github_grpc_grpc/src/compiler/cpp_plugin.h:37:41: error: only virtual member functions can be marked 'override'
  uint64_t GetSupportedFeatures() const override {
                                        ^~~~~~~~~
external/com_github_grpc_grpc/src/compiler/cpp_plugin.h:38:12: error: use of undeclared identifier 'FEATURE_PROTO3_OPTIONAL'
    return FEATURE_PROTO3_OPTIONAL;
           ^
3 errors generated.
INFO: Elapsed time: 2.072s, Critical Path: 1.95s
INFO: 10 processes: 10 darwin-sandbox.
FAILED: Build did NOT complete successfully

Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs).

See TROUBLESHOOTING.md for how to diagnose problems better.

Anything else we should know about your project / environment?

У меня проблема с компиляцией этого кода g++ -std=c++11 аргумент:

#include <iostream>
#include <unordered_map>
#include <functional>
#include <iostream>
using namespace std;;

template <typename T> class opt {
public:
opt() {};
~opt() {};
virtual int isEmpty() = 0;
virtual T getObject() = 0;
};

template <typename T> class oopt : public opt<T> {
private:
T ret;
public:
oopt(T obj) { ret = obj; };
~oopt() override;
int isEmpty() { return 0; };
T getObject() { return ret; };
};
int main(void) {

function<opt<int>(int)> fu = [](int j) { return (oopt<int>(10)); };

return 1;
}

Этот код возвращает следующую ошибку:

assoc_array.cc: In instantiation of ‘class oopt<int>’:
assoc_array.cc:68:63:   required from here
assoc_array.cc:29:3: error: ‘oopt<T>::~oopt() [with T = int]’ marked override, but does not override
In file included from assoc_array.cc:3:0:
/usr/include/c++/4.7/functional: In instantiation of ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = opt<int>; _Functor = main()::<lambda(int)>; _ArgTypes = {int}]’:
/usr/include/c++/4.7/functional:2298:6:   required from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = main()::<lambda(int)>; _Res = opt<int>; _ArgTypes = {int}; typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = std::function<opt<int>(int)>::_Useless]’
assoc_array.cc:68:67:   required from here
/usr/include/c++/4.7/functional:1909:7: error: invalid abstract return type for function ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = opt<int>; _Functor = main()::<lambda(int)>; _ArgTypes = {int}]’
assoc_array.cc:7:29: note:   because the following virtual functions are pure within ‘opt<int>’:
assoc_array.cc:11:15: note:     int opt<T>::isEmpty() [with T = int]
assoc_array.cc:12:13: note:     T opt<T>::getObject() [with T = int]
In file included from assoc_array.cc:3:0:
/usr/include/c++/4.7/functional:1912:40: error: cannot allocate an object of abstract type ‘opt<int>’
assoc_array.cc:7:29: note:   since type ‘opt<int>’ has pure virtual functions
In file included from assoc_array.cc:3:0:
/usr/include/c++/4.7/functional:1743:2: error: ‘static _Functor* std::_Function_base::_Base_manager<_Functor>::_M_get_pointer(const std::_Any_data&) [with _Functor = main()::<lambda(int)>]’, declared using local type ‘main()::<lambda(int)>’, is used but never defined [-fpermissive]

Где моя ошибка при использовании замыканий со статическим приведением к интерфейсу? Я уже читал похожие ответы (C ++ и наследование в абстрактных классах, C ++ — «Функция-член не объявлена» в производном классе), но, похоже, во время компиляции не выдается никакой ошибки, если я удаляю определение замыкания. Заранее спасибо.

РЕДАКТИРОВАТЬ

Даже со следующим кодом:

#include <iostream>
#include <unordered_map>
#include <functional>
#include <iostream>
using namespace std;;

template <typename T> class opt {
public:
opt<T>(T) {};
~opt<T>() {};
virtual int isEmpty() = 0;
virtual T getObject() = 0;
};

template <typename T> class oopt : public opt<T> {
private:
T ret;
public:
oopt<T>(T obj) { ret = obj; };
~oopt<T>() override;
int isEmpty() { return 0; };
T getObject() { return ret; };
};
int main(void) {

function<opt<int>(int)> fu = [](int j) { return (oopt<int>(10)); };

return 1;
}

У меня все еще есть следующие проблемы компиляции:

assoc_array.cc: In instantiation of ‘class oopt<int>’:
assoc_array.cc:26:64:   required from here
assoc_array.cc:20:4: error: ‘oopt<T>::~oopt() [with T = int]’ marked override, but does not override
assoc_array.cc: In instantiation of ‘oopt<T>::oopt(T) [with T = int]’:
assoc_array.cc:26:64:   required from here
assoc_array.cc:19:19: error: no matching function for call to ‘opt<int>::opt()’
assoc_array.cc:19:19: note: candidates are:
assoc_array.cc:9:4: note: opt<T>::opt(T) [with T = int]
assoc_array.cc:9:4: note:   candidate expects 1 argument, 0 provided
assoc_array.cc:7:30: note: constexpr opt<int>::opt(const opt<int>&)
assoc_array.cc:7:30: note:   candidate expects 1 argument, 0 provided
In file included from assoc_array.cc:3:0:
/usr/include/c++/4.7/functional: In instantiation of ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = opt<int>; _Functor = main()::<lambda(int)>; _ArgTypes = {int}]’:
/usr/include/c++/4.7/functional:2298:6:   required from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = main()::<lambda(int)>; _Res = opt<int>; _ArgTypes = {int}; typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = std::function<opt<int>(int)>::_Useless]’
assoc_array.cc:26:68:   required from here
/usr/include/c++/4.7/functional:1909:7: error: invalid abstract return type for function ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = opt<int>; _Functor = main()::<lambda(int)>; _ArgTypes = {int}]’
assoc_array.cc:7:30: note:   because the following virtual functions are pure within ‘opt<int>’:
assoc_array.cc:11:16: note:     int opt<T>::isEmpty() [with T = int]
assoc_array.cc:12:14: note:     T opt<T>::getObject() [with T = int]
In file included from assoc_array.cc:3:0:
/usr/include/c++/4.7/functional:1912:40: error: cannot allocate an object of abstract type ‘opt<int>’
assoc_array.cc:7:30: note:   since type ‘opt<int>’ has pure virtual functions
In file included from assoc_array.cc:3:0:
/usr/include/c++/4.7/functional:1743:2: error: ‘static _Functor* std::_Function_base::_Base_manager<_Functor>::_M_get_pointer(const std::_Any_data&) [with _Functor = main()::<lambda(int)>]’, declared using local type ‘main()::<lambda(int)>’, is used but never defined [-fpermissive]

1

Решение

поскольку gcc является стандартным компилятором, его ошибки не самые очевидные, даже с C ++, чем с C, так что я обычно компилирую все с помощью clang и gcc просто для уверенности.
составлено с лязгом:
у меня есть это с кодом Ааронмана, т

clang++ -std=c++11 test.cc                                                                                                                                                                              ~
test.cc:20:20: error: only virtual member functions can be marked 'override'
~oopt<T>() override;
^~~~~~~~
test.cc:26:54: note: in instantiation of template class 'oopt<int>' requested here
function<opt<int>(int)> fu = [](int j) { return (oopt<int>(10)); };
^
test.cc:19:9: error: constructor for 'oopt<int>' must explicitly initialize the base class 'opt<int>' which does not have a default constructor
oopt<T>(T obj) { ret = obj; };
^
test.cc:26:54: note: in instantiation of member function 'oopt<int>::oopt' requested here
function<opt<int>(int)> fu = [](int j) { return (oopt<int>(10)); };
^
test.cc:7:29: note: 'opt<int>' declared here
template <typename T> class opt {
^
2 errors generated.

и это для вашего первого:

clang++ -std=c++11 test2.cc                                                                                                                                                                             ~
test2.cc:20:17: error: only virtual member functions can be marked 'override'
~oopt() override;
^~~~~~~~
test2.cc:26:54: note: in instantiation of template class 'oopt<int>' requested here
function<opt<int>(int)> fu = [](int j) { return (oopt<int>(10)); };
^
1 error generated.

после исправления этих ошибок Clang дал мне это во время ссылки:

clang++ -o -std=c++11 test2.o -Wall -Werror                                                                                                                                                             ~
test2.o: In function `std::_Function_handler<opt<int> (int), main::$_0>::_M_invoke(std::_Any_data const&, int)':
test2.cc:(.text+0x1a7): undefined reference to `oopt<int>::~oopt()'
test2.o:(.rodata._ZTV4ooptIiE[_ZTV4ooptIiE]+0x10): undefined reference to `oopt<int>::~oopt()'
test2.o:(.rodata._ZTV4ooptIiE[_ZTV4ooptIiE]+0x18): undefined reference to `oopt<int>::~oopt()'
clang: error: linker command failed with exit code 1 (use -v to see invocati

на)

это не точный ответ, но это может очень помочь

1

Другие решения

Хорошо, сначала избавимся от переопределения и сделаем деструктор виртуальным (они всегда должны быть при наследовании). Также деструктор не реализован в базовом классе

#include <iostream>
#include <unordered_map>
#include <functional>
#include <iostream>
using namespace std;;

template <typename T> class opt {
public:
opt() {};
virtual ~opt() {};
virtual int isEmpty() = 0;
virtual T getObject() = 0;
};

template <typename T> class oopt : public opt<T> {
private:
T ret;
public:
oopt(T obj) { ret = obj; };
~oopt(){};
int isEmpty() { return 0; };
T getObject() { return ret; };
};
int main(void) {

function<opt<int>(int)> fu = [](int j) { return (oopt<int>(10)); };

return 1;
}

Это компилируется сейчас. Что касается ошибок, которые вы получали изначально, я не могу сказать, откуда они исходили, так как я их не получил

0

Хорошо, надеюсь, что мое решение верное: по крайней мере, оно компилируется :). Я оставлю это как ответ, чтобы получить дополнительные комментарии относительно решения. Еще раз спасибо.

#include <iostream>
#include <unordered_map>
#include <functional>
#include <iostream>
#include <memory>

using namespace std;

//I need shared_pointers in order to gain the C++ dynamic casting
template <typename T> class Ptr {
shared_ptr<T> ptr;

public:
Ptr(T* obj) : ptr{obj} {};
Ptr(shared_ptr<T> obj) : ptr{obj} {};

~Ptr() {  };

template <typename U> Ptr<U> Cast();

T* operator->() const  {return &(*this->ptr);}
operator T() const { return (*this->ptr); };

};

template <typename T> template <typename U> Ptr<U> Ptr<T>::Cast(){
return Ptr<U>{dynamic_pointer_cast<U>(ptr)};
};template <typename T> class opt {
protected:
T ret;
public:
~opt() {};
virtual int isEmpty() = 0;
virtual T* getObject() = 0;
operator T() const { return ret; };
};

template <typename T> class oopt : public opt<T> {
public:
oopt(T obj) {
this->ret = obj;
};
int isEmpty() { return 1; };
T* getObject() { return &this->ret; }
};

template <typename T> class eopt : public opt<T> {
public:
eopt() { };  //for downcasting matters
T* getObject() { return nullptr; } //
int isEmpty() { return 1; };
};

int main(void) {

Ptr<oopt<int>> u(new oopt<int>(500));
Ptr<opt<int>> w = u.Cast<opt<int>>();
cout << (*(w->getObject())) << "n" ;

Ptr<opt<int>> none(new eopt<int>());
w = none.Cast<opt<int>>();
if ((w->getObject()) == nullptr) {
cout << "null" << "n";
}

return 1;

}

0

When buildiung on Mac OSX 10.11 with Xcode 7.3 the following error occurs:

05:30:33][Step 2/2] /Applications/Xcode.app/Contents/Developer/usr/bin/make -f Makefile.Debug install
[05:30:33][Step 2/2] Makefile.Debug:3139: warning: overriding commands for target `.moc/debug/main.moc’
[05:30:33][Step 2/2] Makefile.Debug:2411: warning: ignoring old commands for target `.moc/debug/main.moc’
[05:30:34][Step 2/2] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -c -pipe -stdlib=libc++ -g -fPIC -std=c++11 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -mmacosx-version-min=10.7 -fvisibility=hidden -fvisibility-inlines-hidden -fno-exceptions -Wall -W -fPIC -DQT_NO_MTDEV -DQT_NO_LIBUDEV -DQT_NO_EVDEV -DQT_NO_TSLIB -DQT_NO_LIBINPUT -DQT_NO_EXCEPTIONS -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_STATICPLUGIN -DQT_PLUGIN -DQT_PLATFORMSUPPORT_LIB -DQT_PRINTSUPPORT_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -I../../../../include -I../../../../include/QtPlatformSupport -I../../../../include/QtPlatformSupport/5.6.0 -I../../../../include/QtPlatformSupport/5.6.0/QtPlatformSupport -I../../../../include/QtPrintSupport/5.6.0 -I../../../../include/QtPrintSupport/5.6.0/QtPrintSupport -I../../../../include/QtWidgets/5.6.0 -I../../../../include/QtWidgets/5.6.0/QtWidgets -I../../../../include/QtGui/5.6.0 -I../../../../include/QtGui/5.6.0/QtGui -I../../../../include/QtPrintSupport -I../../../../include/QtWidgets -I../../../../include/QtGui -I../../../../include/QtCore/5.6.0 -I../../../../include/QtCore/5.6.0/QtCore -I../../../../include/QtCore -I.moc/debug -I../../../../mkspecs/macx-clang -o .obj/debug/qcocoaintegration.o qcocoaintegration.mm
[05:30:53][Step 2/2] In file included from qcocoaintegration.mm:37:
[05:30:53][Step 2/2] ./qcocoabackingstore.h:54:28: error: only virtual member functions can be marked ‘override’
[05:30:53][Step 2/2] QImage toImage() const Q_DECL_OVERRIDE;
[05:30:53][Step 2/2] ^~~~~~~~~~~~~~~
[05:30:53][Step 2/2] ../../../../include/QtCore/../../src/corelib/global/qcompilerdetection.h:1023:26: note: expanded from macro ‘Q_DECL_OVERRIDE’
[05:30:53][Step 2/2] # define Q_DECL_OVERRIDE override
[05:30:53][Step 2/2] ^
[05:30:54][Step 2/2] 1 error generated.
[05:30:54][Step 2/2] make[6]: *** [.obj/debug/qcocoaintegration.o] Error 1
[05:30:54][Step 2/2] make[5]: *** [debug-install] Error 2
[05:30:54][Step 2/2] make[4]: *** [sub-cocoa-install_subtargets] Error 2
[05:30:54][Step 2/2] make[3]: *** [sub-platforms-install_subtargets] Error 2
[05:30:54][Step 2/2] make[2]: *** [sub-plugins-install_subtargets] Error 2
[05:30:54][Step 2/2] make[1]: *** [sub-src-install_subtargets] Error 2
[05:30:54][Step 2/2] make: ***odule-qtbase-install_subtargets] Error 2
[05:30:54][Step 2/2] Process exited with code 2

Full build log attached. The following steps are done to build the code:

perl init-repository —berlin

ROOT=’%system.teamcity.build.checkoutDir%’
export PATH=»$ROOT/qtbase/bin:$PATH»

./configure -prefix «$ROOT/output» -continue -debug-and-release -opensource -confirm-license -nomake tools -nomake examples -nomake tests -skip qtxmlpatterns -skip qtmultimedia -skip qtwebkit -skip qtwebkit-examples -c++11 -static -qt-sql-sqlite -no-icu -openssl-linked -strip -no-dbus -no-audio-backend -no-qml-debug -no-opengl -largefile

make

  • Forum
  • General C++ Programming
  • Base class function is executed despite

Base class function is executed despite of overriding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Dog
{
public:
    void bark()
    {
        cout << "A generic dog has spoken" << endl;
    }

    void seeCat()
    {
        bark();
    }
};

class GentleDog : public Dog
{
public:
    void bark()
    {
	cout << "woof-woof I won't eat you woof-woof!" << endl;
    }
};

The bark() method is overridden in the GentleDog derived class.

BUT, if I write:

1
2
GentleDog pet;   
pet.seeCat();

The pet.seeCat() will call the base class Dog::seeCat() method since there is no override.

The Dog::seeCat() method calls the Dog’s bark() method, not GentleDog’s one.

THE SOLUTION IS SIMPLE: add ‘virtual’ to the bark() method in the Dog class

No, I didn’t want to know the solution.

I want to know WHY Dog::bark() was called although we used a GentleDog object?

If I write

1
2
GentleDog pet;
pet.bark();

Of course the GentleDog::bark() will be called.

But why wasn’t it the case in the first example?

Last edited on

But why wasn’t it the case in the first example?

Because if you trust dog’s with human constructs like inheritance they will still obey their master.

If you don’t use virtual the function is overloaded, not overriden. Which version of overloaded functions to call is always decided at compile time based on the static types involved. Inside Dog::seeCat() the static type of the object (*this) is Dog so that is why it calls Dog::bark().

Last edited on

Tip: Use the override specifier when the intent is to override a virtual function, and the compiler will catch situations where the intent is not met.
http://en.cppreference.com/w/cpp/language/override

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>

namespace one
{
    struct Dog
    {
        void bark()
        { std::cout << "A generic dog has spokenn" ; }
    } ;

    struct GentleDog : public Dog
    {
        void bark() override // *** oops: not virtual
                             // *** error: only virtual member functions can be marked 'override'
        { std::cout << "woof-woof I won't eat you woof-woof!n" ; }
    };
}

namespace two
{
    struct Dog
    {
        virtual void bark() const
        { std::cout << "A generic dog has spokenn" ; }
    } ;

    struct GentleDog : public Dog
    {
        virtual void bark() override // *** oops: forgot the const
                                     // *** error: 'bark' marked 'override' but does not override any member functions
        { std::cout << "woof-woof I won't eat you woof-woof!n" ; }
    };
}

http://coliru.stacked-crooked.com/a/3ae492ccc6524d01

Topic archived. No new replies allowed.

Понравилась статья? Поделить с друзьями:
  • Error only nop and sig tag can be recevied before authentication что делать
  • Error only constructors take member initializers
  • Error only 0 items available перевод
  • Error online migrate failure remote command failed with exit code 255
  • Error one пылесос xiaomi