加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C继承函数覆盖

发布时间:2020-12-16 10:31:43 所属栏目:百科 来源:网络整理
导读:我是C的新手,我来自 Java / C#. 我知道在Java和C#中你可以创建一个类,让另一个类继承它,并覆盖它的功能.然后,您可以创建父类的列表,并将子类的对象插入此列表中.之后,您可以使用被覆盖的功能. 例: public class Parent{ public virtual void test() { Conso
我是C的新手,我来自 Java / C#.

我知道在Java和C#中你可以创建一个类,让另一个类继承它,并覆盖它的功能.然后,您可以创建父类的列表,并将子类的对象插入此列表中.之后,您可以使用被覆盖的功能.

例:

public class Parent
{
  public virtual void test()
  {
    Console.WriteLine("test");
  }
}

public class Child : Parent
{
  public override void test()
  {
    Console.WriteLine("test2");
  }
}

用法:

List<Parent> tests = new List<Parent>();
tests.Add(new Child());
tests[0].test();

输出:

06002

在C中,当我使用std :: vector执行此操作时,它调用父项的成员函数,而不是子项的函数.

我怎样才能在C中完成上述操作?

解决方法

我觉得这里有两个问题.一个是语法问题,其他人已经解决了.但是,您似乎也有尝试在C中编写Java / C#代码的潜在问题.无论语法问题是什么,这都会导致痛苦,所以我试着在这里解决这个问题.

In c++ when I do this with vector it calls that parent’s function. How can I do the example above in C++?

Java和C#使用面向对象的范例来实现一切. C的不同之处在于C是一种多范式语言.它支持(或多或少)结构化,面向对象,通用,功能和诸如编程范例.你可以自由地混合和混合范式,而C在你做到这一点的时候会闪亮.

源自STL的标准库的一部分,即:容器,算法,迭代器,根本不是OO.他们正在应用通用编程.其中一个属性是容器通常(有异常,但不在标准库本身内)存储值,而不是引用.然而,多态性,至少是运行时多态性,仅对引用(或语法上的指针,也是语义上的引用)进行操作.

如果你有一个std :: vector< base_class> vc,这将存储实际值,而不是对堆上某处对象的引用.如果将对象放入这样的容器中,该对象实际上将被复制到容器中.如果你输入一个derived_class对象,那么它将被切片.也就是说,只有它的base_class部分将被复制到容器中,所有的derived_class部分都将被忽略.然后,您最终在容器中得到一个实际的base_class对象,而不是像在Java和C#中那样,是对堆上某个派生类对象的基类引用.
这就是为什么在该对象上调用成员函数将最终在基类中:没有派生类对象来调用函数.

在C中,如果要使用OOP,通常必须动态分配派生类对象(即new derived_class())并将它们分配给基类指针.这个问题是C没有垃圾收集,所以你必须跟踪那些指针,以及从中生成的所有副本,并在最后一个指针被销毁之前显式删除对象.手动操作非常容易出错,这就是为什么现在每个人都让智能指针自动执行此操作.

所以你想要的是std :: vector< smart_ptr< base_class>>并放入新的derived_class()对象.符号smart_ptr所指的内容取决于您的需求.如果你计划在那个容器中存储指向这些对象的指针,std :: unique_ptr(std :: tr1 :: unique_ptr如果你的编译器只支持C 03,或者boost :: unique_ptr,如果它甚至不支持)是理想的.如果你自由地传递这样的指针,并且它们跟踪最后一次超出自己的范围,std :: shared_ptr会更好.

现在,所有这些说,我觉得有必要补充:你可能根本不需要OO方式.如果你可以放弃刚刚认真考虑Java和C#监禁你的OO,可能会有更好的设计.

如果您使用多态,那么您可以将具有不同内容的容器传递给相同的算法,那么使用通用编程可能会好得多:

template<typename FwdIt>
void do_something(FwdIt begin,FwdIt end)
{
  while(begin != end)
    if(begin->foo() == bar()) // whatever
      begin->baz();           // whatever
}

std::vector<some_class> vs;
std::vector<other_class> vo;
std::deque<other_class> do;

// ...

do_something(vs.begin(),vs.end());
do_something(vo.begin(),vo.end());
do_something(do.begin(),do.end());

这适用于所有类型(这里是some_class),其中foo()成员不接受任何参数并返回与bar()返回的内容相当的东西,并且具有baz()成员,也不接受任何参数. (如果你尝试使用某些没有那些类型的类型,编译器会咆哮你.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读