出于某种原因,GCC和clang的最新版本在此特定方案中无法识别返回类型协方差.错误消息具有误导性:
error: return type of virtual function 'foo' is not covariant with the return
type of the function it overrides ('derived *' is not derived from 'base *')
Run Code Online (Sandbox Code Playgroud)
这是代码:
class base
{
private:
virtual base * foo() = 0;
};
template< class T >
class foo_default_impl : public virtual base
{
private:
T * foo() override { return nullptr; }
};
class derived : public virtual base, private foo_default_impl< derived >
{
};
int main() {
derived d{}; // error: …
Run Code Online (Sandbox Code Playgroud) 在 C++ 中,如何在不使用 reset 和 new 的情况下使用纯抽象类的共享指针?
这个例子有点做作,但说明了我遇到的问题。
看看run()
方法:reset
有效,但注释掉的行不......
#include <iostream>
#include <map>
#include <memory>
using namespace std;
class Interf {
public:
virtual void doSomething()=0;
};
class Foo : public Interf {
public:
Foo() { cout << "Foo constructed\n"; }
shared_ptr<Interf> innerInterf;
void doSomething() {
cout << "Foo:doSomething()\n";
innerInterf->doSomething();
}
void run() {
cout << "run() called\n";
innerInterf.reset(new Bar()); // this works
//Bar b;
//innerInterf = make_shared<Interf>((Interf)b); // how can i get this to work?
} …
Run Code Online (Sandbox Code Playgroud) 给定两个类只有原始数据类型,没有自定义析构函数/解除分配器.C++规范是否保证它将以正确的大小解除分配?
struct A { int foo; };
struct B: public A { int bar[100000]; };
A *a = (A*)new B;
delete a;
Run Code Online (Sandbox Code Playgroud)
我想知道我需要写一个空的virtual
dtor吗?
我试过g ++和vc ++ 2008,它们不会导致泄漏.但我想知道C++标准中的正确性.
error: use of deleted function 'A::A(const A&)'
return tmp;
^~~
Run Code Online (Sandbox Code Playgroud)
为什么仅在其中存在虚拟析构函数时才调用复制构造函数A
?如何避免这种情况?
struct B {};
struct A{
std::unique_ptr<B> x;
virtual ~A() = default;
};
A f() {
A tmp;
return tmp;
}
Run Code Online (Sandbox Code Playgroud) 我发现几乎每个虚拟析构函数的代码片段都将它作为公共成员函数,如下所示:
class Base
{
public:
virtual ~Base()
{
cout << "~Base()" << endl;
}
};
class Derived : public Base
{
public:
~Derived()
{
cout << "~Derived()" << endl;
}
};
Run Code Online (Sandbox Code Playgroud)
虚拟析构函数必须是公共的还是存在非公共虚拟析构函数有意义的情况?
删除阻止虚拟方法传播的能力的原因是什么?
让我更清楚一点:在C++中,无论你在派生类中编写"virtual void foo()"还是"void foo()",只要在基类中,它就是虚拟的,foo被声明为虚拟.
这意味着通过派生*指针调用foo()将导致虚拟表查找(如果derived2函数覆盖foo),即使程序员不希望这种行为.
让我举一个关于如何停止虚拟传播有用的例子(对我来说看起来很明显):
template <class T>
class Iterator // Here is an iterator interface useful for defining iterators
{ // when implementation details need to be hidden
public:
virtual T& next() { ... }
...
};
template <class T>
class Vector
{
public:
class VectIterator : public Iterator<T>
{
public:
T& next() { ... }
...
};
...
};
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,Iterator基类可用于以更清晰和面向对象的方式实现"类型擦除"的形式.(有关类型擦除的示例,请参见http://www.artima.com/cppsource/type_erasure.html.)
但是,在我的示例中,可以直接使用Vector :: VectIterator对象(在大多数情况下将完成),以便在不使用接口的情况下访问真实对象.
如果没有传播虚拟性,即使从指针或引用调用Vector :: VectIterator :: next()也不是虚拟的,并且能够内联并高效运行,就像Iterator接口不存在一样.
/*Child is inherited from Parent*/
class Parent {
public:
Parent () //Constructor
{
cout << "\n Parent constructor called\n" << endl;
}
protected:
~Parent() //Dtor
{
cout << "\n Parent destructor called\n" << endl;
}
};
class Child : public Parent
{
public:
Child () //Ctor
{
cout << "\nChild constructor called\n" << endl;
}
~Child() //dtor
{
cout << "\nChild destructor called\n" << endl;
}
};
int main ()
{
Parent * p2 = new Child;
delete p2;
return …
Run Code Online (Sandbox Code Playgroud) 缺少虚拟继承会对以下代码产生负面影响吗?
如果是这样,如果class A
确实包含数据成员,那么负面影响是否会与没有虚拟继承的多重继承的负面影响相同(或者更糟)?
class A
{
public :
virtual ~A ( ) { }
virtual int foo ( ) const = 0 ;
} ;
class B : public A
{
public :
virtual ~B ( ) { }
} ;
class C : public A
{
public :
virtual ~C ( ) { }
} ;
class D : public B , public C
{
public :
virtual int foo ( ) const { return 12 …
Run Code Online (Sandbox Code Playgroud) c++ oop inheritance multiple-inheritance virtual-inheritance
我遇到的问题是,据我所知,删除操作符应该是一个静态函数,但有时编译器(VC++)似乎将它视为动态.
鉴于:
class Base
{
public:
void* operator new(size_t size) { /* allocate from custom heap */ }
void operator delete(void *p) { customFree(p, sizeof(Base)); }
Base() {}
virtual ~Base() {}
};
class Derived: public Base
{
public:
void* operator new(size_t size) { /* allocate from custom heap */ }
void operator delete(void *p) { customFree(p, sizeof(Derived)); }
Derived() {}
virtual ~Derived() {}
}
Run Code Online (Sandbox Code Playgroud)
我看到的是删除基指针将导致调用Derived::opeator
删除.
Base *p = new Derived();
delete p; //calls Derived::operator delete
Run Code Online (Sandbox Code Playgroud)
如果我没有定义任何析构函数,那么我得到了我预期的结果:调用Base …
(在msvc2017上测试)
struct AAA
{
virtual float run(int arg)
{
return 5.5f;
}
};
struct BBB : AAA
{
virtual bool run(double arg)
{
return false;
}
};
struct CCC : BBB
{
virtual float run(int arg)
{
return 7.7f;
}
virtual bool run(double arg)
{
return true;
}
};
CCC c;
BBB* pb = &c;
pb->run(5); // call CCC::run(double arg), WHY??
pb->run((int)5); // call CCC::run(double arg), WHY??
Run Code Online (Sandbox Code Playgroud)
为什么pb->run(5)
只打电话CCC::run(double arg)
,却不打电话CCC::run(int arg)
?
具有不同签名的子类的虚拟方法是否与基类的接口重叠?
c++ ×10
inheritance ×3
virtual ×2
class ×1
destructor ×1
memory ×1
memory-leaks ×1
oop ×1
overriding ×1
polymorphism ×1
protected ×1
templates ×1
type-erasure ×1