C++ 压倒一切的几个基本问题
我的基本功没有什么问题,如果有人能帮我解决这个问题,我将不胜感激 1:我说base*b是什么意思 =新导出的;为什么有人会这么做?我们完全可以分开 为基类和类创建对象 类,然后调用 相应地发挥作用。我知道 这个基数*b=新的导出值;是 称为对象切片,但为什么和 什么时候可以买这个 2:我知道 为什么不建议转换 要派生的基类对象 类对象(因为基类是 不知道派生类 成员和方法)。我甚至在报纸上读过 其他StackOverflow线程,如果 情况就是这样,然后我们 必须更改/重新访问我们的设计。 我明白这一切,但是,我 只是好奇,有什么办法吗 这个C++ 压倒一切的几个基本问题,c++,polymorphism,overloading,overriding,C++,Polymorphism,Overloading,Overriding,我的基本功没有什么问题,如果有人能帮我解决这个问题,我将不胜感激 1:我说base*b是什么意思 =新导出的;为什么有人会这么做?我们完全可以分开 为基类和类创建对象 类,然后调用 相应地发挥作用。我知道 这个基数*b=新的导出值;是 称为对象切片,但为什么和 什么时候可以买这个 2:我知道 为什么不建议转换 要派生的基类对象 类对象(因为基类是 不知道派生类 成员和方法)。我甚至在报纸上读过 其他StackOverflow线程,如果 情况就是这样,然后我们 必须更改/重新访问我们的设计。 我明
class base
{
public:
void f(){cout << "In Base";}
};
class derived:public base
{
public:
void f(){cout << "In Derived";}
};
int _tmain(int argc, _TCHAR* argv[])
{
base b1, b2;
derived d1, d2;
b2 = d1;
d2 = reinterpret_cast<derived*>(b1); //gives error C2440
b1.f(); // Prints In Base
d1.f(); // Prints In Derived
b2.f(); // Prints In Base
d1.base::f(); //Prints In Base
d2.f();
getch();
return 0;
}
类基
{
公众:
void f(){cout是和否。你可以走了
派生类:公共基{
public:void f(){base::f();}
};
但是,我不太确定是否在全局范围内。问题1:为什么要这样做:您可能不会直接这样做。发生这种情况的情况是,例如,您有一个返回“某种基*”的函数,而您不关心它的类型
问题2:在派生中,您需要使用范围解析操作符来指定要使用基类的实现
注意:您尚未声明您的函数为虚拟函数,因此您实际上不会得到预期的行为
base *b = new derived
正在创建指向派生类对象的基类指针。这允许您创建is-a关系。派生类是基类。有关详细信息,请参阅
2.d2=重新解释铸件(b1);
您正在尝试将基类对象转换为派生类对象。但所使用的强制转换操作不正确
若您计划调用基类方法,那个么就使用基类指针
Base* ptr = &b1;
ptr->f();
我建议您参考。1。这不是对象切片:
base *b = new derived;
这是将类型为base
的指针分配给派生的
的实例
<>这个动作中的一个(非常常见的)例子是回调。考虑一下:
class Observer
{
public:
virtual void OnEvent() = 0;
};
class Subject
{
public:
Subject() : observer(0) {}
void SetObserver(Observer* o) { observer = o; }
void FireEvent() { if(observer != 0) observer->OnEvent(); }
private:
Observer* observer;
};
class MyObserver : public Observer
{
public:
void OnEvent() { ::printf("Hi there!\n"); }
};
int main()
{
Subject s;
MyObserver o;
s.SetObserver(&o);
s.FireEvent();
return 0;
}
这应该是预期的输出:
你好
注意这里发生的事情。我们将一个指向MyObserver
实例的指针传递到SetObserver()
,即使该函数只接受Observer
类型的指针。这是因为MyObserver
(公开)派生自Observer
。在本例中,我们说MyObserver
是一个观察者
Observer
类型定义了一个纯虚函数(=0
表示该函数是纯函数;它必须由派生类实现。)virtual
关键字告诉编译器调用该函数应该导致执行最派生的函数。OnEvent()MyObserver
中的
函数是最派生的,因此,即使我们在Observer
类型的指针上调用OnEvent()
,也会调用该版本
我们经历了这么多的麻烦,因为在这个代码中,Subject
不需要知道它的观察者的确切类型-观察者只需要从observer
派生,Subject
实例将调用最派生类型的OnEvent()实现
。这允许代码解耦-主题
不依赖于MyObserver
,MyObserver
不依赖于主题
2.将指针从基类型强制转换为派生类型本身并没有错。以下事实上是合法的,并保证有效:
class Base {};
class Derived : public Base {};
int main()
{
Derived d;
Base* bp = &d;
Derived* dp = static_cast<Derived*>(bp);
return 0;
}
如果Foobar()
函数不是虚拟函数,则您将获得以下输出:
In Derived!
In Base!
In Derived!
In Derived!
否则,如果Foobar()
In Derived!
In Base!
In Derived!
In Derived!
要确保对虚拟函数Foobar()
的调用通过基指针调用基实现,则必须使用范围解析运算符:
// Prints "In Base!", even if bp actually points
// to an instance of Derived overriding Foobar().
bp->Base::Foobar();
(1) 您有一个指向派生类对象的基类指针。这是在实现多态性时使用的,在多态性中,您有几个派生类继承自一个公共基类。然后,您可以通过基类指针根据其类型调用正确的派生类函数,前提是该函数是虚拟的
class base
{
public:
virtual void f(){ cout << "In Base" << endl; }
};
class derived:public base
{
public:
void f(){ cout << "In Derived" << endl; }
};
class derived2: public derived
{
public:
void f() { cout << "In Derived2" << endl; }
};
int _tmain(int argc, _TCHAR* argv[])
{
derived d1;
derived2 d2;
base* b;
b = &d1;
b->f(); // calls derived::f();
b = &d2;
b->f(); // calls derived2::f();
return 0;
}
它也不称为对象切片。对象切片是指将派生类对象分配给基类对象(不是指针),其中派生类对象的成员被切片,因此无法从基类对象访问这些切片的成员
(2) 除了使用reinterpret_cast的行之外,其他语句都可以
(3) 如果使用对象或重写派生类函数来调用基类版本(如其他答案中所述),则必须使用范围解析运算符。但是,可以使用指针:
derived *d = static_cast( &b1 );
d->f();
请重新格式化以隔离代码。单击语法指南的小问号。感谢您清理了我的代码格式。我可以编辑我的问题吗/我没有看到任何编辑按钮。因为,从“我知道为什么不建议将基类对象转换为派生对象…”开始的语句是我的第二个问题,但它错误地附加到了第一个问题。大致修复了这个问题。您应该在问题下方看到一个编辑按钮。base*b=新派生;不是对象切片。对象切片发生在您按值赋值时,例如,base b=d;,其中d是派生的实例。“The=0
表示函数是纯函数-它不存在”-不完全,表示派生
derived *d = static_cast( &b1 );
d->f();