Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

method return object bug

120 views
Skip to first unread message

Lynn McGuire

unread,
Mar 9, 2018, 10:50:27 PM3/9/18
to
OK, to simplify, I have the following classes:

class ObjPtr;
class DataItem : public ObjPtr;
class DataGroup : public ObjPtr;
class CrudeGroup : public DataGroup;

I have a base method in ObjPtr:
virtual ObjPtr * dataTransferItemsToDIIW (int key);

I have a method in CrudeGroup:
virtual DataItem * dataTransferItemsToDIIW (int key);

Why am I not getting a compiler error from Visual Studio C++ 2015 that
the return types do not match ?

Is it because I am not using the override keyword in the function
declaration ?
http://en.cppreference.com/w/cpp/language/override

Thanks,
Lynn

Ian Collins

unread,
Mar 10, 2018, 12:00:22 AM3/10/18
to
On 03/10/2018 04:50 PM, Lynn McGuire wrote:
> OK, to simplify, I have the following classes:
>
> class ObjPtr;
> class DataItem : public ObjPtr;
> class DataGroup : public ObjPtr;
> class CrudeGroup : public DataGroup;
>
> I have a base method in ObjPtr:
> virtual ObjPtr * dataTransferItemsToDIIW (int key);
>
> I have a method in CrudeGroup:
> virtual DataItem * dataTransferItemsToDIIW (int key);
>
> Why am I not getting a compiler error from Visual Studio C++ 2015 that
> the return types do not match ?
>
> Is it because I am not using the override keyword in the function
> declaration ?

Nothing to do with override, more like a compiler bug if you have what
you say you have.

--
Ian.

Alf P. Steinbach

unread,
Mar 10, 2018, 12:29:02 AM3/10/18
to
No, it's because C++ supports covariant raw pointer and raw reference
return types.

In short, in a more specialized class the virtual member function can
have a more specialized return type (with "X* more specialized than Y*"
== "X is indirectly or directly derived from Y").

This works fine for using the more specialized class' implementation
where you call the base class function.

For more details check out the literature on the Liskov Substitution
Principle (LSP).

C++ does not support ditto contravariant in-arguments, I think mainly
because there's no C++ way of denoting pointer or reference argument
referents as pure in-direction; the C++ `const` doesn't quite cut it.

And C++ does not support the notion of covariant code, such as a `clone`
member function that has the same textual definition in every class, but
gets more specialized in more specialized classes.

So, the support that is there is the bare minimum needed to define
general covariant virtual member functions, but as far as it goes (which
is very short) it's nice.


Cheers & hth.,

- Alf

Louis Krupp

unread,
Mar 10, 2018, 12:39:40 AM3/10/18
to
This file:

===============================
class ObjPtr
{
public:
virtual ObjPtr * dataTransferItemsToDIIW (int key);
};

class DataItem : public ObjPtr
{
};

class DataGroup : public ObjPtr
{
};

class CrudeGroup : public DataGroup
{
public:
virtual DataItem * dataTransferItemsToDIIW (int key);
};
===============================

compiles with g++ version 7.3.1. As I understand it, since DataItem is
derived from ObjPtr, a pointer to a DataItem is also a pointer to an
ObjPtr, so someone calling ObjPtr::dataTransferItemstoDIIW() would get
the expected return type.

Looking at this program and its output might help:

===============================
#include <iostream>

struct c1
{
c1() : a(1), b(2) {}
int a, b;
};

struct c2 : c1
{
c2() : c(3), d(4) {}
int c, d;
};

int main()
{
c2 x;
c2* p2 = &x;
c1* p1 = p2;

std::cout << p1 << ' ' << p1->a << ' ' << p1->b << "\n";
std::cout << p2 << ' ' << p2->a << ' ' << p2->b << ' '
<< p2->c << ' ' << p2->d << "\n";

return 0;
}
===============================

Louis

Cholo Lennon

unread,
Mar 10, 2018, 1:31:05 AM3/10/18
to
On 03/10/2018 02:28 AM, Alf P. Steinbach wrote:
> On 10.03.2018 04:50, Lynn McGuire wrote:
>> OK, to simplify, I have the following classes:
>>
>>     class ObjPtr;
>>     class DataItem : public ObjPtr;
>>     class DataGroup : public ObjPtr;
>>     class CrudeGroup : public DataGroup;
>>
>> I have a base method in ObjPtr:
>>     virtual ObjPtr * dataTransferItemsToDIIW (int key);
>>
>> I have a method in CrudeGroup:
>>     virtual DataItem * dataTransferItemsToDIIW (int key);
>>
>> Why am I not getting a compiler error from Visual Studio C++ 2015 that
>> the return types do not match ?
>>
>> Is it because I am not using the override keyword in the function
>> declaration ?
>>     http://en.cppreference.com/w/cpp/language/override
>
> No, it's because C++ supports covariant raw pointer and raw reference
> return types.

+1

>
> In short, in a more specialized class the virtual member function can
> have a more specialized return type (with "X* more specialized than Y*"
> == "X is indirectly or directly derived from Y").
>
> This works fine for using the more specialized class' implementation
> where you call the base class function.
>
> For more details check out the literature on the Liskov Substitution
> Principle (LSP).
>
> C++ does not support ditto contravariant in-arguments, I think mainly
> because there's no C++ way of denoting pointer or reference argument
> referents as pure in-direction; the C++ `const` doesn't quite cut it.
>
> And C++ does not support the notion of covariant code, such as a `clone`
> member function that has the same textual definition in every class, but
> gets more specialized in more specialized classes.
>
> So, the support that is there is the bare minimum needed to define
> general covariant virtual member functions, but as far as it goes (which
> is very short) it's nice.
>
>
> Cheers & hth.,
>
> - Alf


--
Cholo Lennon
Bs.As.
ARG

wyn...@gmail.com

unread,
Mar 10, 2018, 7:50:16 AM3/10/18
to
Alf P. Steinbach於 2018年3月10日星期六 UTC+8下午1時29分02秒寫道:
> On 10.03.2018 04:50, Lynn McGuire wrote:
> > OK, to simplify, I have the following classes:
> >
> >    class ObjPtr;
> >    class DataItem : public ObjPtr;
> >    class DataGroup : public ObjPtr;
> >    class CrudeGroup : public DataGroup;
> >
> > I have a base method in ObjPtr:
> >    virtual ObjPtr * dataTransferItemsToDIIW (int key);
> >
> > I have a method in CrudeGroup:
> >    virtual DataItem * dataTransferItemsToDIIW (int key);
> >
> > Why am I not getting a compiler error from Visual Studio C++ 2015 that
> > the return types do not match ?
> >
> > Is it because I am not using the override keyword in the function
> > declaration ?
> >    http://en.cppreference.com/w/cpp/language/override
>
> No, it's because C++ supports covariant raw pointer and raw reference
> return types.
>
> In short, in a more specialized class the virtual member function can
> have a more specialized return type (with "X* more specialized than Y*"
> == "X is indirectly or directly derived from Y").
>

I used to saw 'derived' or 'inheriting' in this case, not 'specialized'.
Has the standard doc. changed term?

> This works fine for using the more specialized class' implementation
> where you call the base class function.
>
> For more details check out the literature on the Liskov Substitution
> Principle (LSP).
>
> C++ does not support ditto contravariant in-arguments, I think mainly
> because there's no C++ way of denoting pointer or reference argument
> referents as pure in-direction; the C++ `const` doesn't quite cut it.
>
> And C++ does not support the notion of covariant code, such as a `clone`
> member function that has the same textual definition in every class, but
> gets more specialized in more specialized classes.
>
> So, the support that is there is the bare minimum needed to define
> general covariant virtual member functions, but as far as it goes (which
> is very short) it's nice.
>

Are you talking about 'the clone' member function?

struct B {
virtual B* clone();
}

struct D : B {
virtual D* clone();
}

I have such one in my library, a bit tedious and harder to use.
sad to hear that support is minimum (almost 0)

Lynn McGuire

unread,
Mar 10, 2018, 7:03:58 PM3/10/18
to
So I do need to use the override keyword always in order to get a proper
method lookup. Bummer.

Lynn

Ian Collins

unread,
Mar 10, 2018, 7:11:37 PM3/10/18
to
No, you don't. Why do you object to using it?

--
Ian.

Louis Krupp

unread,
Mar 10, 2018, 10:15:47 PM3/10/18
to
I don't believe adding "override" to the declaration of
CrudeGroup::dataTransferItemsToDIIW will make any difference. The code
you posted is legal either way.

Louis

Lynn McGuire

unread,
Mar 11, 2018, 10:56:31 PM3/11/18
to
in DCrudeOptionsDialog::command, I call:
CrudeGroup * crudeGroup = owner -> getCrudeGroup;

this gives me the ObjPtr method instead of the CrudeGroup method:
ObjPtr * anObject = crudeGroup -> dataTransferItemsToDIIW (key);

This is because the ObjPtr and CrudeGroup methods have different return
types. The only way that I see to force the compiler to flag the
improper return type is to use the override keyword. The compiler is
allowing the multiple return types until I tell it to only allow one
return type by use of the override keyword.

Thanks,
Lynn

Louis Krupp

unread,
Mar 11, 2018, 11:30:19 PM3/11/18
to
Could you post a small example that reproduces the problem you're
talking about -- i.e., code that compiles but shouldn't?

Thanks!

Louis

Ian Collins

unread,
Mar 12, 2018, 12:47:09 AM3/12/18
to
That makes very little, if any, sense!

Please provide a test case.

--
Ian

Richard

unread,
Mar 12, 2018, 2:17:41 AM3/12/18
to
[Please do not mail me a copy of your followup]

Lynn McGuire <lynnmc...@gmail.com> spake the secret code
<p84q8n$6l1$1...@dont-email.me> thusly:

>in DCrudeOptionsDialog::command, I call:
> CrudeGroup * crudeGroup = owner -> getCrudeGroup;
>
>this gives me the ObjPtr method instead of the CrudeGroup method:
> ObjPtr * anObject = crudeGroup -> dataTransferItemsToDIIW (key);
>
>This is because the ObjPtr and CrudeGroup methods have different return
>types. The only way that I see to force the compiler to flag the
>improper return type is to use the override keyword. The compiler is
>allowing the multiple return types until I tell it to only allow one
>return type by use of the override keyword.

Virtual methods are allowed to be covariant by return type so long as
the covariant return types share an inheritance relationship. See
<http://en.cppreference.com/w/cpp/language/virtual#Covariant_return_types>

If you use the override keyword in this case and get a compile error,
that is a bug in the compiler.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

James Kuyper

unread,
Mar 12, 2018, 12:21:23 PM3/12/18
to
On 03/11/2018 10:56 PM, Lynn McGuire wrote:
> On 3/10/2018 6:11 PM, Ian Collins wrote:
>> On 03/11/2018 01:03 PM, Lynn McGuire wrote:
>>> On 3/9/2018 11:28 PM, Alf P. Steinbach wrote:
>>>> On 10.03.2018 04:50, Lynn McGuire wrote:
>>>>> OK, to simplify, I have the following classes:
>>>>>
>>>>>      class ObjPtr;
>>>>>      class DataItem : public ObjPtr;
>>>>>      class DataGroup : public ObjPtr;
>>>>>      class CrudeGroup : public DataGroup;
>>>>>
>>>>> I have a base method in ObjPtr:
>>>>>      virtual ObjPtr * dataTransferItemsToDIIW (int key);
>>>>>
>>>>> I have a method in CrudeGroup:
>>>>>      virtual DataItem * dataTransferItemsToDIIW (int key);
>>>>>
>>>>> Why am I not getting a compiler error from Visual Studio C++ 2015 that
>>>>> the return types do not match ?
>>>>>
>>>>> Is it because I am not using the override keyword in the function
>>>>> declaration ?
>>>>>      http://en.cppreference.com/w/cpp/language/override

Alf has already given a good answer this question, but I'm answering it
in more detail with citations from the standard below, so I'm clipping
his answer.

>>> So I do need to use the override keyword always in order to get a proper
>>> method lookup.  Bummer.
>>
>> No, you don't.  Why do you object to using it?
>
> in DCrudeOptionsDialog::command, I call:
> CrudeGroup * crudeGroup = owner -> getCrudeGroup;
>
> this gives me the ObjPtr method instead of the CrudeGroup method:
> ObjPtr * anObject = crudeGroup -> dataTransferItemsToDIIW (key);


I wrote the simplest program I could come up with that contains all of
the actual lines of code that you've provided, and is consistent with
the descriptions you've give us, and is instrumented to produce output
addressing the issues you've raised. It is, I believe, well-formed code
with standard-defined behavior. As you can see from the output, it calls
the CrudeGroup version of dataTransferItemsToDIIW:

~/Programming/C++/testprog(70) cat covariant_return.cpp
// Based upon a message posted by Lynn McGuire <lynnmc...@gmail.com>
// to comp.lang.c++ with Date:Fri, 9 Mar 2018 21:50:13 -0600.
#include <iostream>
class ObjPtr
{
public:
virtual ObjPtr * dataTransferItemsToDIIW (int key){
std::cout << this << " ObjPtr::dataTransferItemsToDIIW(" << key
<< ")" << std::endl;
return this;
};
virtual ~ObjPtr() {};
};

class DataItem : public ObjPtr{
};

class DataGroup : public ObjPtr{
};

class CrudeGroup : public DataGroup
{
public:
virtual CrudeGroup * dataTransferItemsToDIIW (int key){
std::cout << this << " CrudeGroup::dataTransferItemsToDIIW(" <<
key << ")" << std::endl;
return this;
};
} crudeGroup;

struct Owner{
CrudeGroup *getCrudeGroup;
} actual = {&crudeGroup}, *owner = &actual;

struct DCrudeOptionsDialog
{
void command(int key)
{
CrudeGroup * crudeGroup = owner -> getCrudeGroup;
ObjPtr * anObject = crudeGroup -> dataTransferItemsToDIIW (key);
std::cout << "owner:" << owner << " crudeGroup:" << crudeGroup
<< " anObject:" << anObject << std::endl;
}
} dialog;

int main(void)
{
dialog.command(0);
}

~/Programming/C++/testprog(71) g++ -std=c++1y -pedantic -Wall
-Wpointer-arith -Wcast-align -fno-enforce-eh-specs -ffor-scope
-fno-gnu-keywords -fno-nonansi-builtins -Wctor-dtor-privacy
-Wnon-virtual-dtor -Wold-style-cast -Woverloaded-virtual -Wsign-promo
covariant_return.cpp -o covariant_return
~/Programming/C++/testprog(72) ./covariant_return
0x602078 CrudeGroup::dataTransferItemsToDIIW(0)
owner:0x602080 crudeGroup:0x602078 anObject:0x602078


> This is because the ObjPtr and CrudeGroup methods have different return
> types.

Which is permitted - section 10.3p7 says:

"The return type of an overriding function shall be either identical to
the return type of the overridden function or covariant with the classes
of the functions. If a function D::f overrides a function B::f, the
return types of the functions are covariant if they satisfy the
following criteria:
(7.1) — both are pointers to classes, both are lvalue references to
classes, or both are rvalue references to classes 112
(7.2) — the class in the return type of B::f is the same class as the
class in the return type of D::f, or is an unambiguous and
accessible direct or indirect base class of the class in the
return type of D::f
(7.3) — both pointers or references have the same cv-qualification and
the class type in the return type of D::f has the same
cv-qualification as or less cv-qualification than the class type
in the return type of B::f."

> ... The only way that I see to force the compiler to flag the
> improper return type is to use the override keyword.

It's not improper, so there's no need to flag it. The sole effect of the
"override" keyword is to make it an error if the function it applies to
does NOT override a virtual member of one of it's base classes.

The return type has nothing to do with whether something is a function
override. The requirements for being an override are:

"If a virtual member function vf is declared in a class Base and in a
class Derived, derived directly or indirectly from Base, a member
function vf with the same name, parameter-type-list (8.3.5),
cv-qualification, and ref-qualifier (or absence of same) as Base::vf is
declared, then Derived::vf is also virtual (whether or not it is so
declared) and it overrides 111 Base::vf." (10.3p2)

It's an error for an overriding function to have a return type that
violates 10.3p7, but it's still an override, or 10.3p7 wouldn't even
apply. Therefore, if "override" causes an error message, it's because,
in your actual code, there is some feature that causes
CrudeGroup::dataTransferItemsToDIIW() to fail to qualify as an override
of ObjPtr::dataTransferItemsToDIIW(). There's no such reason in the code
you've posted, so there's probably a relevant difference between your
actual code and the code you posted. When I inserted the override
keyword in my code, I got no complaint.

> ... The compiler is
> allowing the multiple return types until I tell it to only allow one
> return type by use of the override keyword.

That's NOT what the override keyword tells it.

Lynn McGuire

unread,
Mar 12, 2018, 2:48:59 PM3/12/18
to
Yes, you are correct. I need the compiler to flag this code for me to
fix when I changed the function of the method dataTransferItemsToDIIW:

DataItem * anObject = crudeGroup -> dataTransferItemsToDIIW (key);

I have several classes that I need to fix:

C:\dii\deswin\classes>grep dataTransferItemsToDIIW *.h
compregr.h: virtual DataItem * dataTransferItemsToDIIW (int key);
comsplgr.h: virtual DataItem * dataTransferItemsToDIIW (int key);
crudegro.h: virtual ObjPtr * dataTransferItemsToDIIW (int key);
datagrou.h: virtual ObjPtr * dataTransferItemsToDIIW (int key,
DataGroup ** theDataItemOwner);
disgroup.h: virtual ObjPtr * dataTransferItemsToDIIW (int key,
DataGroup ** theDataItemOwner) override;
divgroup.h: virtual DataItem * dataTransferItemsToDIIW (int key);
expgroup.h: virtual DataItem * dataTransferItemsToDIIW (int key);
flashgro.h: virtual DataItem * dataTransferItemsToDIIW (int key);
gengroup.h: virtual DataItem * dataTransferItemsToDIIW (int key);
hx1group.h: virtual DataItem * dataTransferItemsToDIIW (int key);
hx2group.h: virtual DataItem * dataTransferItemsToDIIW (int key);
linegrou.h: virtual DataItem * dataTransferItemsToDIIW (int key);
muldivgr.h: virtual DataItem * dataTransferItemsToDIIW (int key);
plureagr.h: virtual DataItem * dataTransferItemsToDIIW (int key);
streamgr.h: virtual ObjPtr * dataTransferItemsToDIIW (int key,
DataGroup ** theDataItemOwner) override;
tankgroup.h: virtual DataItem * dataTransferItemsToDIIW (int key);
valvegro.h: virtual DataItem * dataTransferItemsToDIIW (int key);

Thanks,
Lynn

Richard

unread,
Mar 12, 2018, 3:37:26 PM3/12/18
to
[Please do not mail me a copy of your followup]

Lynn McGuire <lynnmc...@gmail.com> spake the secret code
<p86i2g$nip$1...@dont-email.me> thusly:

>Yes, you are correct. I need the compiler to flag this code for me to
>fix when I changed the function of the method dataTransferItemsToDIIW:
>
> DataItem * anObject = crudeGroup -> dataTransferItemsToDIIW (key);

IMO, the best way to drive this change is to write tests for the
covariant derived methods and then the compiler will fail when you
attempt to assign Base* to Derived* without a downcast.

Lynn McGuire

unread,
Mar 12, 2018, 7:51:30 PM3/12/18
to
OK, one of my programmers just told me that I am an idiot since the
arguments on all of the methods are not identical. That is why I am not
getting compilation errors. And why I am not getting the proper
function called. I did have some glue code before but I deleted it when
I first started working on this project.

Thanks
Lynn

Richard

unread,
Mar 12, 2018, 8:48:18 PM3/12/18
to
[Please do not mail me a copy of your followup]

Lynn McGuire <lynnmc...@gmail.com> spake the secret code
<p873po$od3$1...@dont-email.me> thusly:

>OK, one of my programmers just told me that I am an idiot since the
>arguments on all of the methods are not identical. That is why I am not
>getting compilation errors. And why I am not getting the proper
>function called. I did have some glue code before but I deleted it when
>I first started working on this project.

Well, if you add override keyword on a virtual method in a derived class
for which there is no matching(*) method on a base class, then that
should generate a compile error.

(*) "Matching" means matching the argument list and not the possibly
covariant return type:

shell 192> g++ --std=c++11 a.cpp
shell 193> ./a.out
shell 194> cat a.cpp
#include <cassert>
#include <type_traits>

struct Base
{
virtual Base* clone() { return this; }
};

struct Derived : Base
{
Derived *clone() override { return this; }
};

int main()
{
Base b;
assert((std::is_same<decltype(b.clone()), Base *>::value));
Derived d;
assert((std::is_same<decltype(d.clone()), Derived *>::value));

Lynn McGuire

unread,
Mar 13, 2018, 6:31:19 PM3/13/18
to
Done.

C:\dii\deswin\classes>grep dataTransferItemsToDIIW *.h
compregr.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
comsplgr.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
crudegro.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
datagrou.h: virtual ObjPtr * dataTransferItemsToDIIW (int key);
disgroup.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
divgroup.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
expgroup.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
flashgro.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
gengroup.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
hx1group.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
hx2group.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
linegrou.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
muldivgr.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
plureagr.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
streamgr.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
tankgroup.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
valvegro.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;

Thanks,
Lynn

Richard

unread,
Mar 14, 2018, 11:41:49 AM3/14/18
to
[Please do not mail me a copy of your followup]

Lynn McGuire <lynnmc...@gmail.com> spake the secret code
<p89jfc$bu7$1...@dont-email.me> thusly:

>On 3/12/2018 7:48 PM, Richard wrote:
>> Well, if you add override keyword on a virtual method in a derived class
>> for which there is no matching(*) method on a base class, then that
>> should generate a compile error.
>
>Done.
>
>C:\dii\deswin\classes>grep dataTransferItemsToDIIW *.h
>compregr.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>comsplgr.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>crudegro.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;

>datagrou.h: virtual ObjPtr * dataTransferItemsToDIIW (int key);

Presumably this is the base class from which others derive?

>disgroup.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>divgroup.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>expgroup.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>flashgro.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>gengroup.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>hx1group.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>hx2group.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>linegrou.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>muldivgr.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>plureagr.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>streamgr.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>tankgroup.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;
>valvegro.h: virtual ObjPtr * dataTransferItemsToDIIW (int key) override;

I see you are on Windows. If you use ReSharper for C++, the latest
version has clang-tidy integration and can apply the "use override"
quick fix individually, on a whole file, or on a whole project/solution.

There is also a free "Clang Power Tools" extension that can run
clang-tidy on your code. I have not used that tool, however.

If you use clang-tidy to automatically apply the override keyword, you
may be surprised to see that it adds override to your virtual
destructors. There is debate about the usefulness of adding the
override keyword in this case. See
<https://bugs.llvm.org/show_bug.cgi?id=30397>

It also drops the "virtual" keyword on overridden methods because it
is redundant. You can't override a non-virtual method and adding
override to a method in a derived class for which there is no matching
virtual base class method is a compile error.

Lynn McGuire

unread,
Mar 14, 2018, 2:58:06 PM3/14/18
to
ObjPtr -> DataGroup -> NodeGroup -> StreamGroup
-> EquipGroup -> ComPreGroup
-> ComSplGroup
-> ...

Yes, DataGroup is the base class for that particular method.

Thanks,
Lynn

0 new messages