我正在尝试学习C++,并编写了这段代码.根据我的理解,这段代码需要产生输出,"Derived Class"但输出是"Base Class".请帮我理解这个.
#include <iostream>
using namespace std;
class Base {
public:
char* name;
void display() {
cout << name << endl;
}
Run Code Online (Sandbox Code Playgroud)
};
class Derived: public Base {
public:
char* name;
void display() {
cout << name << ", " << Base::name << endl;
}
};
int main() {
Derived d;
d.name = "Derived Class";
d.Base::name = "Base Class";
Derived* dptr = &d;
Base* bptr = dptr;
bptr->display();
}
Run Code Online (Sandbox Code Playgroud)
请考虑我作为初学者,并解释为什么它的输出 "Base Class"
我正在尝试一个项目,它需要我在运行时确定多态对象的类型,以便我可以投射它.我的意思的一个例子:
class A{
};
class B: public A{
public:
void foo(){
printf("B::foo()\n");
}
};
Run Code Online (Sandbox Code Playgroud)
稍后,我将有一堆B对象基本上存储如下:
std::vector<A*> v;
v.push_back(new B());
Run Code Online (Sandbox Code Playgroud)
我需要调用某些定义为的重载方法:
void bar(B* b){
b->foo();
}
Run Code Online (Sandbox Code Playgroud)
传入存储的对象后v.我遇到的问题是,在我的实际用例中,我不知道B编译时的类型,所以我不能只是bar通过说bar((B*)v.get(0));
我一直以为我可能需要的解决方案是以某种方式确定每个对象在运行时的类型,以便我可以在将它传递给它之前将其强制转换bar.
我到目前为止尝试的解决方案是使用decltype,但它对我不起作用,因为它只返回传入的值的静态类型,而不是运行时的类型.
此外,我不想在这个项目中使用第三方库,因为我希望尽可能小.
谢谢您的帮助.
编辑:
当我描述我的问题时,我认为我的意思并不清楚.在我的实际用例中(虽然我可以在这里发布,但是我可以发布它的部分内容有点长),我正在尝试编写一个库,其中有一个基类(在此表示为A),可以扩展由用户进入自己的自定义类(此处表示为B).在我的例子中,B::foo()简单地应该表示每个子类如何A拥有自己的数据成员,稍后由某种方法处理(在我的例子中表示为bar).这也是为什么A不能简单地拥有一些虚拟foo方法的原因.
我遇到的主要问题是,因为B应该是用户定义的,我不知道它在编译时是什么,但我在链接时做(因为链接后来).这就是为什么dynamic_cast(正如Sam和Remy所建议的)的使用不起作用的原因,因为根据我的理解,它要求我知道什么是B可能的,但我不知道.虽然它看起来非常接近可能对我有用的东西.如果有某种方法可以获得所有可能的子类(例如,使用预处理器宏或模板),那么我认为这可能会起作用.
我希望这次我能更好地解释它.再次感谢你的帮助.
编辑2:另一个澄清点:在我正在进行的实际项目中,我只希望用户需要编写自己的B类并重载bar以使用他们的自定义类.但是,我不希望要求用户打电话bar.相反,我希望bar从基类(我定义)中调用.这就是我尝试这样做的主要原因.那,并看看我能不能.
希望清除一切.再次感谢你.
我想知道肖恩家长,其实就是 被这句话
对于继承层次结构中的多态类型,具有可变对象是极端例外...
他继续提到两个原因,但是我很难理解他的解释。
是什么让我无法在子类中提供实际上更改此对象内部结构的函数?
有人可以详细说明一下吗?
这个问题在stackoverflow.com/q/2391679上进行
功能的一个典型例子virtual是
class Shape
{
public:
virtual string draw() = 0;
};
class Circle : public Shape
{
public:
string draw() { return "Round"; }
};
class Rectangle : public Shape
{
public:
string draw() { return "Flat"; }
};
void print (Shape& obj)
{
cout << obj.draw();
}
Run Code Online (Sandbox Code Playgroud)
但是,我们可以auto在C++ 14中传递一个参数
class Circle
{
public:
string draw() { return "Round"; }
};
class Rectangle
{
public:
string draw() { return "Flat"; }
};
void print …Run Code Online (Sandbox Code Playgroud) 我在采访中向我询问,因为我提到OOPS是我最喜欢的主题.
任何人都可以为动态多态性和运算符重载提供一些真实的例子吗?
我只能在编码方面进行解释,比如计算不同形状的区域(虚函数+重写)和添加复数或串联连接(运算符重载).
为什么我们需要在c ++中使用接口(纯虚函数或抽象类)?我们可以在其中定义具有虚函数的基类,并在派生类中重写该虚函数,而不是使用抽象类.上述方法的优点和缺点是什么(除了我们可以创建基类的对象)?
我正在尝试使用中的装饰器设计模式c++。但是,如果没有抽象超类(核心和装饰类都从中继承),我将无法实现它。
我不明白为什么需要抽象超类。
我的工作装饰器示例:
#include <string>
#include <iostream>
using namespace std;
// abstract superclass
class Pizza
{
public:
virtual string GetDescription() = 0;
virtual int GetCost() = 0;
};
// base class that can be extended
class Margharita: public Pizza
{
private:
string description;
int cost;
public:
Margharita(string t, int c){description = t; cost = c;}
string GetDescription(){return(description);}
int GetCost(){return(cost);}
};
// decorator class that extends base class
class ExtraCheese: public Pizza
{
private:
Pizza* pizza;
public:
// constructor …Run Code Online (Sandbox Code Playgroud) 我对C ++中的多态感到困惑。我正在自己研究它,并且了解它的主要功能。但是我不明白为什么会有帮助。在研究多态性(关于oop)之前,我研究了继承(这很有用,因为您只能在一次超类和子类的编写中使用一个方法)。现在,我被多态性和virtual关键字所困扰。我不明白为什么会有帮助。请参阅下面的代码(这是有关C ++研究所的练习(我将获得认证))。为什么可以将仅虚函数声明为“虚”函数?我添加的代码中的变量n1,n2,n3(公开),为什么我不能访问它们?我根本不了解多态性,我在StackOverflow上阅读了很多有关多态性的文章,但这就像我了解50%的多态性一样。我注意到在python中了解多态性比较困难,因为python没有数据类型,但是我也想在C ++中理解它,以及它的可能用途。
#include <iostream>
using namespace std;
class Pet {
protected:
string Name;
public:
Pet(string n) { Name = n; }
virtual void MakeSound(void) { cout << Name << " the Pet says: Shh! Shh!" << endl; }
int n1;
};
class Cat : public Pet {
public:
Cat(string n) : Pet(n) { }
void MakeSound(void) { cout << Name << " the Cat says: Meow! Meow!" << endl; } …Run Code Online (Sandbox Code Playgroud) 我尝试了很多方法来解决这个问题,但是没有一个起作用。我想要达到的目标是这个。
我有这样的课。
class Auton {
public:
int slot;
const char * name;
void run();
};
Run Code Online (Sandbox Code Playgroud)
我要做的是使run函数执行不同的操作。例如 -
// The code below doesn't work, unfortunately :(
Auton one;
void one::run() {
// Do something here
}
Auton two;
void two::run() {
// Do something different here
}
Run Code Online (Sandbox Code Playgroud)
这可能吗?
为什么要d.f(1)调用Derived::f此代码?
是否using Base::f决定其发挥作用f将被调用?
#include <iostream>
using namespace std;
struct Base {
void f(int){
cout << "\n f(Base) is called" ;
}
};
struct Derived : Base {
using Base::f ; // using-declarations but still Drived function is called
void f(int){
cout << "\n f(Derived) is called" ;
}
};
void use(Derived d)
{
d.f(1); // calls Derived::f
Base& br = d ;
br.f(1); // calls Base::f
}
int main() {
Derived d; …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用具有相同基类的不同子类指针的向量。该向量设置为基类指针,但是添加到该向量的任何内容都无法获得其子类的全部功能。在错误日志中可以看到,它被视为基类,因此未获得扩展功能。
我查看了很多问题,人们说要按照我的方式去做,但是由于某种原因,它没有用。
该代码位于公共仓库中:
https://repl.it/@cubingminer8/inheritance-with-vectors-testing
任何帮助将不胜感激!
编辑:确定,所以我将在c ++ sdl2游戏引擎中将其用于子画面组系统。将有一个基本的Sprite类,其中包含一些基本的东西,例如render和move,而我需要的任何sprite都是它们自己的继承自Sprite的类,它们将具有自己的独特行为,因此虚函数是不切实际的。将有一个sprite组对象,可以将继承自Sprite的对象存储在其中。这样就可以一次全部渲染它们。
如果您曾经使用过pygame,那么它几乎与那里使用的sprite和spritegroup系统相同。 https://www.pygame.org/docs/tut/SpriteIntro.html
#include <iostream>
#include <vector>
class Base {
public:
char A = 'A';
};
class Sub : public Base {
public:
char B = 'B';
};
class Sub2 : public Base {
public:
char C = 'C';
};
int main() {
std::vector<Base*> List;
List.push_back(new Sub());
List.push_back(new Sub2());
std::cout << List[0]->B << std::endl; // it should be able to print B
std::cout << List[1]->C << std::endl; // but it is …Run Code Online (Sandbox Code Playgroud) c++ ×10
polymorphism ×5
inheritance ×4
oop ×2
auto ×1
c++11 ×1
c++14 ×1
class ×1
decorator ×1
reflection ×1
stdvector ×1
templates ×1
virtual ×1