与新运算符c ++的静态绑定
static binding with new operator c++
我想确定我是否理解正确。如果我有这样的东西:
Base* wsk = new Derived
如果我用静态绑定完成了,而不是 wsk 是 Base 类型,但派生类型对象仍然被创建?而 wsk
指向的是 Derived 类型对象,但是它不能使用派生 class 的方法,因为 wsk
是 Base 类型?总结一下对我来说最重要的问题是,如果 wsk
除了它的 Base 类型仍然指向 Derived 类型的新对象?
wsk
是 Base *
类型,而不是 Base
或 Derived
.
它使用从类型 Derived *
(隐式)转换而来的值进行初始化。它指向一个 Base
对象,该对象恰好驻留在 Derived
对象中。
这意味着 static_cast<Derived *>(wsk)
会给你一个指向 Derived
的值。
可能wsk
的表示和static_cast<Derived *>(wsk)
的表示是同一个数,即 Base
对象的地址与 Derived
对象的地址相同,但不能保证
一个重要的评论,如上所述,当查看 Base *
时,它指向类型 Base
。我没有使用这个符号来简化解释。
你问的是另一个问题:静态类型和dynamic/runtime类型有什么区别一个对象。
让我们观察下面的代码:
#import <iostream>
class Base
{
public:
virtual void foo()
{
std::cout << "From Base" << std::endl;
}
};
class A : public Base
{
public:
void foo() override
{
std::cout << "From A" << std::endl;
}
void some_A_only_function()
{
std::cout << "some function from A" << std::endl;
}
};
class B : public Base
{
public:
void foo() override
{
std::cout << "From B" << std::endl;
}
void some_B_only_function()
{
std::cout << "some function from B" << std::endl;
}
};
int main()
{
Base base{};
Base * a = new A();
Base * b = new B();
base.foo();
a->foo();
// a->some_A_only_function(); this won't compile: error: no member named 'some_A_only_function' in 'Base'
b->foo();
// b->some_B_only_function(); this won't compile either!!
}
输出为:
From Base
From A
From B
这里的所有对象都来自Base
的静态类型,因此,您不能调用任何不属于Base
的函数,因为编译器不能 知道在运行时将哪种类型放在那里。如果我们有覆盖函数,将根据运行时类型调用适当的函数(这称为 dynamic dispatch)。
总而言之,这里有3个对象:
- 静态类型
Base
和动态类型 Base
的对象。
- 静态类型
Base
和动态类型 A
的对象。
- 静态类型
Base
和动态类型 B
的对象。
分别使用 A
或 B
函数的唯一方法是使用强制转换,以便 "return"他们变成原来的样子。但应谨慎操作!
重要说明: 这在任何提供多态性的语言中都是如此(据我所知)。它不是 C++ 独有的!
我想确定我是否理解正确。如果我有这样的东西:
Base* wsk = new Derived
如果我用静态绑定完成了,而不是 wsk 是 Base 类型,但派生类型对象仍然被创建?而 wsk
指向的是 Derived 类型对象,但是它不能使用派生 class 的方法,因为 wsk
是 Base 类型?总结一下对我来说最重要的问题是,如果 wsk
除了它的 Base 类型仍然指向 Derived 类型的新对象?
wsk
是 Base *
类型,而不是 Base
或 Derived
.
它使用从类型 Derived *
(隐式)转换而来的值进行初始化。它指向一个 Base
对象,该对象恰好驻留在 Derived
对象中。
这意味着 static_cast<Derived *>(wsk)
会给你一个指向 Derived
的值。
可能wsk
的表示和static_cast<Derived *>(wsk)
的表示是同一个数,即 Base
对象的地址与 Derived
对象的地址相同,但不能保证
一个重要的评论,如上所述,当查看 Base *
时,它指向类型 Base
。我没有使用这个符号来简化解释。
你问的是另一个问题:静态类型和dynamic/runtime类型有什么区别一个对象。
让我们观察下面的代码:
#import <iostream>
class Base
{
public:
virtual void foo()
{
std::cout << "From Base" << std::endl;
}
};
class A : public Base
{
public:
void foo() override
{
std::cout << "From A" << std::endl;
}
void some_A_only_function()
{
std::cout << "some function from A" << std::endl;
}
};
class B : public Base
{
public:
void foo() override
{
std::cout << "From B" << std::endl;
}
void some_B_only_function()
{
std::cout << "some function from B" << std::endl;
}
};
int main()
{
Base base{};
Base * a = new A();
Base * b = new B();
base.foo();
a->foo();
// a->some_A_only_function(); this won't compile: error: no member named 'some_A_only_function' in 'Base'
b->foo();
// b->some_B_only_function(); this won't compile either!!
}
输出为:
From Base
From A
From B
这里的所有对象都来自Base
的静态类型,因此,您不能调用任何不属于Base
的函数,因为编译器不能 知道在运行时将哪种类型放在那里。如果我们有覆盖函数,将根据运行时类型调用适当的函数(这称为 dynamic dispatch)。
总而言之,这里有3个对象:
- 静态类型
Base
和动态类型Base
的对象。 - 静态类型
Base
和动态类型A
的对象。 - 静态类型
Base
和动态类型B
的对象。
分别使用 A
或 B
函数的唯一方法是使用强制转换,以便 "return"他们变成原来的样子。但应谨慎操作!
重要说明: 这在任何提供多态性的语言中都是如此(据我所知)。它不是 C++ 独有的!