这些都是一样的:
int foo(bar* p) {
return p->someInt();
}
Run Code Online (Sandbox Code Playgroud)
和
int foo(bar& r) {
return r.someInt();
}
Run Code Online (Sandbox Code Playgroud)
忽略空指针潜力.这两个函数在功能上是否相同,无论它们someInt()
是虚拟的还是传递给它们bar
的子类bar
?
这会切片吗:
bar& ref = *ptr_to_bar;
Run Code Online (Sandbox Code Playgroud) 我想在向量中存储几个类的实例.由于所有类都继承自相同的基类,因此这是可能的.
想象一下这个程序:
#include <iostream>
#include <vector>
using namespace std;
class Base
{
public:
virtual void identify ()
{
cout << "BASE" << endl;
}
};
class Derived: public Base
{
public:
virtual void identify ()
{
cout << "DERIVED" << endl;
}
};
int main ()
{
Derived derived;
vector<Base> vect;
vect.push_back(derived);
vect[0].identify();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望它能打印"DERIVED",因为"识别"方法是虚拟的.相反,'vect [0]'似乎是一个'Base'实例,它打印出来
基础
我想我可以写一个我自己的容器(可能是从vector派生的),不知何故能够做到这一点(也许只能拿指针......).我只是想问一下是否有更多的C++ ish方法来做到这一点.我希望完全兼容矢量(只是为了方便其他用户应该使用我的代码).
I was searching a bug in an application, which I've finally fixed but didn't understand completely. The behavior can be reproduced with the following simple program:
#include <iostream>
#include <memory>
#include <functional>
struct Foo
{
virtual int operator()(void) { return 1; }
};
struct Bar : public Foo
{
virtual int operator()(void) override { return 2; }
};
int main()
{
std::shared_ptr<Foo> p = std::make_shared<Bar>();
std::cout << (*p)() << std::endl;
std::function<int(void)> f;
f = *p;
std::cout << f() << std::endl; …
Run Code Online (Sandbox Code Playgroud) 看过一些相关的问题,但不是这个问题......
我把课程视为适合几个主要类别,让我们说这四个简单:
值类具有一些数据和一堆操作.可以复制它们并进行有意义的比较以获得相等性(通过预期副本相同==
). 这几乎总是缺乏虚拟方法.
唯一的类,其实例具有禁用分配和复制的标识.通常没有operator==
这些,因为你将它们作为指针进行比较,而不是作为对象. 这些通常有很多虚方法,因为没有对象切片的风险,因为你被迫通过指针或引用传递它们.
Unique-but-Clonable类禁用复制,但预先设计为支持克隆,如果这是你真正想要的. 它们具有虚拟方法,最重要的是遵循虚拟构造/克隆习语的方法
容器类继承他们持有的任何属性. 这些往往没有虚拟方法...例如参见"为什么STL容器没有虚拟析构函数?" .
无论持有这种非正式的信仰系统,我都尝试过将虚拟方法添加到可复制的东西中.虽然我可能认为如果"有效"会"真的很酷",但它不可避免地会破裂.
这让我想知道是否有人有一个具有虚拟方法并且不禁用复制的类型的实际好例子?
有时,c ++默认允许切片可能会令人烦恼。例如
struct foo { int a; };
struct bar : foo { int b; };
int main() {
bar x{1,2};
foo y = x; // <- I dont want this to compile!
}
Run Code Online (Sandbox Code Playgroud)
这将编译并按预期运行!但是,如果我不想启用切片怎么办?
什么是惯用的写法,foo
以至于无法对任何派生类的实例进行切片?
当我们将派生类的对象分配或复制到其基类的对象时,会发生对象切片,从而在该过程中丢失它的派生部分.
这里有更深入的解释:C++中的切片问题是什么?.
(我自己,我不认为它是一个问题,而是语言价值语义的自然结果,但这不是这个问题的重点.)
我想知道的是:有没有你有意使用它的情况?这是一个"工作的正确工具"吗?
我如何能:
我试过了:
y = dataframe.iloc[:,-3:]
Run Code Online (Sandbox Code Playgroud)
我试过了:
X = dataframe.iloc[:,:-3]
Run Code Online (Sandbox Code Playgroud)
它是否正确?
我在代码中进一步得到了数组维度错误,并希望确保此步骤正确无误.
谢谢
我没有和我一起使用有效的C++,这让我非常烦恼,所以我必须要求自己的理智.特定
class Foo : public Bar{}
void MyFunc(Bar &_input);
Run Code Online (Sandbox Code Playgroud)
如果我通过了Foo
,我是否与切片问题纠缠在一起还是我避免了它?
我有一个时间了解参考的魔鬼.请考虑以下代码:
class Animal
{
public:
virtual void makeSound() {cout << "rawr" << endl;}
};
class Dog : public Animal
{
public:
virtual void makeSound() {cout << "bark" << endl;}
};
Animal* pFunc()
{
return new Dog();
}
Animal& rFunc()
{
return *(new Dog());
}
Animal vFunc()
{
return Dog();
}
int main()
{
Animal* p = pFunc();
p->makeSound();
Animal& r1 = rFunc();
r1.makeSound();
Animal r2 = rFunc();
r2.makeSound();
Animal v = vFunc();
v.makeSound();
}
Run Code Online (Sandbox Code Playgroud)
结果是:"树皮树皮rawr rawr".
用Java的思维方式(显然已经破坏了我对C++的概念化),结果将是"树皮树皮树皮".我从前一个问题中了解到,这种差异是由切片引起的,我现在对切片的理解有了很好的理解.
但是,让我们说我想要一个返回Animal值的函数,它实际上是一个Dog. …
object-slicing ×10
c++ ×9
inheritance ×3
polymorphism ×2
reference ×2
c++-faq ×1
c++11 ×1
clone ×1
copy ×1
dataframe ×1
indexing ×1
pandas ×1
pointers ×1
python ×1