c++ - vector教學 - vector pop




C++,刪除類頭中的#include<vector>或#include<string> (8)

警告

預計這樣做會引起軒然大波。

該語言允許你派生你自己的類:

// MyKludges.h
#include <vector>
#include <string>
class KludgeIntVector : public std::vector<int> { 
  // ... 
};
class KludgeDoubleVector : public std::vector<double> {
  // ...
};

class KludgeString : public std::string {
  // ...
};

改變你的函數返回KludgeString和KludgeIntVector。 由於這些不再是模板,因此可以在頭文件中將它們轉發聲明,並將MyKludges.h包含在實現文件中。

嚴格來說,派生類不會繼承基類構造函數,析構函數,賦值運算符和朋友。 您將需要提供任何您使用的(微不足道的)實現。

// LotsOfFunctions.h
// Look, no includes!  All forward declared!
class KludgeString;
// 10,000 functions that use neither strings nor vectors
// ...
void someFunction(KludgeString &);
// ... 
// Another 10,000 functions that use neither strings nor vectors

// someFunction.cpp
// Implement someFunction in its own compilation unit
// <string> and <vector> arrive on the next line
#include "MyKludges.h"
#include "LotsOfFunctions.h"
void someFunction(KludgeString &k) { k.clear(); }

如果可能,我想從我的類頭文件中刪除<vector>和<string>。 字符串和向量都是頭文件中聲明的函數的返回類型。

我希望我能做到這樣的事情:

namespace std {
    template <class T>
    class vector;
}

然後,在頭文件中聲明矢量並將其包含在源文件中。

是否有一個參考涵蓋了必須包含在標題中的情況,以及可以將包括到源文件中的情況?


也許你會更好地使用pimpl成語:在我看來,你不希望暴露你的類的實現客戶端代碼。 如果矢量和字符串對象按值進行聚合,編譯器需要查看完整的聲明。


只要在您引用STL集合的任何文件中包含頭文件。

正如其他人所提到的,沒有辦法可靠地轉發聲明STL類,即使你為特定的實現找到一個,如果你使用不同的STL實現,它可能會中斷。

如果編譯單元沒有實例化類,它不會使你的目標文件變大。


如果字符串和向量僅用於您的類的非公共成員的簽名,則可以使用PImpl習慣用法:

// MyClass.h
class MyClassImpl;
class MyClass{
public:
    MyClass();
    void MyMethod();
private:
    MyClassImpl* m_impl;
};

// MyClassImpl.h
#include <vector>
#include <string>
#include <MyClass.h>
class MyClassImpl{
public:
    MyClassImpl();
    void MyMethod();
protected:
    std::vector<std::string> StdMethod();
};

// MyClass.cpp
#include <MyClass.h>
#include <MyClassImpl.h>

void MyClass::MyMethod(){
    m_impl->MyMethod();
}

你總是在頭文件中包含矢量和字符串,但只能在你的類的實現部分; 只包含MyClass.h的文件不會被拉入字符串和向量中。


標準容器通常有額外的默認模板參數(分配器等),所以這是行不通的。 例如,下面是GNU實現的一個片段:


  template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
    class vector : protected _Vector_base<_Tp, _Alloc>
    { ... };

沒有簡單明顯的方法來做到這一點(正如其他人已經很好地解釋過)。

然而,這些標題應該被看作是語言的一部分(真的!),所以你可以讓他們在你自己的標題沒有任何問題,沒有人會抱怨。

如果你關心的是編譯速度,我鼓勵你使用預編譯頭,而不是把這些標頭(除其他外)。 這將顯著提高您的編譯速度。

對不起,對於“真正的勝利者是避免戰鬥的人”的那種回答。


除了極少數例外情況,你不能把東西添加到std中: 命名空間。 對於像vector和string這樣的類,你只能#include相關的標準頭文件。

另請注意,字符串不是類,而是basic_string<char>的typedef。


這也是我之前想要做的,但是由於模板,這是不可能的。

請看我的問題: 提前聲明一個基類

因為這樣的頭文件在開發過程中不會改變,所以無論如何都不值得優化。







include