【问题标题】:Howto extend std::list and create custom function?如何扩展 std::list 并创建自定义函数?
【发布时间】:2018-01-21 21:52:09
【问题描述】:

有一个自定义的 std::list 类助手:

#ifndef __WLIST_H

    #define __WLIST_H

    #include <list>
    using namespace std;

    template <class T >
    class WList : public std::list<T>
    {
        public:
            void wAdd();
            void wRemove();
            bool wContains();
            void wGet();
            void wClear();
            int  wSize();

    };

#endif /*__WLIST_H*/

如何声明自定义add新项目?,在类中声明:

#include "WList.h"

template<class T>
void WList<T>::wAdd(/*???*/)
{
    this->push_back(/*???*/);
}

如何在参数中设置对象类型?

【问题讨论】:

  • 你不能直接将T 类型的类传递给wAdd (void WList&lt;T&gt;::wAdd(T object_to_add)),然后像this-&gt;push_back(object_to_add) 一样添加它吗?
  • 如果您不知道如何声明自定义添加新项目?的答案,您需要了解a good book的语言基础知识。另外,不要从std::list 派生。标准禁止这样做。
  • @apalomer 不起作用,编译器说错误:WList&lt;Rectangle&gt;::wAdd(Rectangle) is not defined
  • @RSahu 一本西班牙语的好书?
  • 西班牙语?这是The Definitive C++ Book Guide and List 的链接。

标签: c++ list std extends


【解决方案1】:

在 C++11 中,如果可用:

模板需要定义在头文件中,可以写在类里面:

void wAdd(T&& obj) { this->push_back(std::move(obj)); }   
void wAdd(const T& obj) { this->push_back(obj); }

您可能还需要考虑 emplace 语义:

template <typename... Ts>
void wEmplace(Ts&&... args) { this->emplace_back(std::forward<Ts>(args)...); }

并且不要在头文件中使用using namespace std;

【讨论】:

    【解决方案2】:

    虽然you should not inherit from stl containers我会用你同样的例子给你答案。

    使用函数或类模板时,您必须实现header file 中的代码,否则编译器将无法实例化正确的函数。定义函数模板时,编译器为给定类创建函数模板的特定类。例如,当您执行WList&lt;Rectangle&gt; 时,编译器会为模板Rectangle 创建WList 的实例。为此,编译器需要正在编译的代码中的所有函数/类模板,否则,某些函数(不在头文件中的函数)将丢失,并出现func is not definedundefined reference to func 错误。

    你的代码应该是这样的:

    WList.h

    #include <list>
    
    template <typename T >
    class WList : public std::list<T>
    {
    public:
        void wAdd(T obj)
        {
            this->push_back(obj);
        }    
    };
    

    #include <list>
    
     template <typename T >
     class WList: public std::list<T>
     {
         public:
             void wAdd(T obj);
    
     };
    
     template<typename T>
     void WList<T>::wAdd(T obj)
     {
         this->push_back(obj);
     }
    

    主要

    int main() {
    
        WList<double> list;
        list.wAdd(2);
    }
    

    更合适的做法是不从 stl 容器继承:

    #include <list>
    
    template <typename T >
    class WList
    {
    public:
        void wAdd(T obj)
        {
            m_data.push_back(obj);
        }    
    protected:
        std::list<T> m_data;
    };
    

    此外,注意在class作为模板和class作为类定义之间,使用template&lt;typename T&gt;优于template&lt;class T&gt;avoid static ambiguity

    【讨论】:

    • 更合适的方式:m_data.push_back(std::move(obj));.
    • 只有当@e-info128 使用c++11 though,不是吗?
    • 如果在标题中声明函数名但在类中声明功能?是WList&lt;T&gt;::wAdd(T obj)?
    • 你可以在类定义之外声明函数,但是如果函数没有在头文件中声明,那么当给定类型的类被实例化时,它就不会被实例化。看看我的编辑。
    猜你喜欢
    • 1970-01-01
    • 2014-02-28
    • 2020-09-28
    • 1970-01-01
    • 2010-10-13
    • 2011-04-26
    • 2021-12-04
    • 2023-04-08
    • 1970-01-01
    相关资源
    最近更新 更多