C继承函数覆盖
我是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(); 输出:
在C中,当我使用std :: vector执行此操作时,它调用父项的成员函数,而不是子项的函数. 我怎样才能在C中完成上述操作? 解决方法
我觉得这里有两个问题.一个是语法问题,其他人已经解决了.但是,您似乎也有尝试在C中编写Java / 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()成员,也不接受任何参数. (如果你尝试使用某些没有那些类型的类型,编译器会咆哮你.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |