2012-07-10 18 views
12

Örnek değişken olarak std::vector<int> olan bir sınıf tasarlıyorum. Boyutu std::vector kullanıyorum çünkü çalışma zamanında boyutunu ayarlamanız gerekiyor. İşte benim kod ilgili kısımları şunlardır:Kurulum std :: vektörü, sınıf yapıcısı

my_class.h: 

#include <vector> 
using std::vector; 
class MyClass { 
    int size; 
    vector<int> vec; 
} 

my_class.cc: 

#include "my_class.h" 
using std::vector 
MyClass::MyClass(int m_size) : size(m_size) { 
    vec = new vector<int>(size,0); 
} 

ben bu hata iletileri almak derlemek girişiminde:

vector<int> temp(size,0); 
vec = temp; 
: Ben kusurlu hattı değiştirdiğinizde, Ancak

g++ -c -Wall my_class.cc -o my_class.o 

my_class.cc: In constructor ‘MyClass::MyClass(int): 

    my_class.cc:4 error: no match for ‘operator=’ in ‘((MyClass*)this)->My_Class::vec = ((*(const allocator_type*)(& std::allocator<int>())), (operator new(24u), (<statement>, ((std::vector<int>*)<anonymous>))))’ 

make: *** [my_class.o] Error 1 

Artık bir aksama olmadan derleniyor ve istenen davranışı alıyorum ve vektörüme

vec[i] // i having been defined as an int yada yada yada 

Bu geçici çözüm tamam, ancak neden çalıştığını ve ilk yöntemin başarısız olduğunu anlamak isterim. Şimdiden teşekkürler.

+2

'yeni vector' size üye değişkeni atamak edebilmek için değil, bir değer, bir işaretçi döndürür' – Chethan

+2

Eğer Java Benim tahminim gelmek olduğunu veya C# ve eğer öyleyse, benim ciddi tavsiyem vec' Önce iyi, giriş C++ kitabı almak için. –

+0

Ve her zaman kopyasını kopyala + yapıştır yöntemiyle gönderin. Gönderdiğiniz kod eksik –

cevap

18

Hemen yapın:

MyClass::MyClass(int m_size) : size(m_size), vec(m_size, 0) 
Zaten başlatıcı listeleri hakkında biliyor gibi

, neden doğrudan oraya vektör başlatılamadı? new bir işaretçi döndürür ve sizin durumunuzda vec bir nesne olduğu için

vec = new vector<int>(size,0); 

yasalara aykırıdır.

İkinci seçeneğiniz: hayır kazanç için derler rağmen

vector<int> temp(size,0); 
vec = temp; 

yapar ekstra çalışma. Ödeve ulaştığınız zaman, daha sonra iki vektör zaten inşa edilmiş ve atılmıştır. Bu vektör nesnesi başlatılmadı sanki yeni bir vektör nesnesine bir işaretçi atama

#include <vector> 

class MyClass { 
public: 
    MyClass(int m_size); 

    // ... more things... 
private: 
    int size; 
    vector<int> vec; 
} 

:

+1

IIRC bu, başlatma sırasına göre GCC ile uyarılara neden olacaktır - başlatıcı listesindeki başlatmaların sınıftaki üye değişkenleriyle aynı şekilde sipariş vermeniz gerekir. – Fiktik

+0

Yorum için teşekkürler, buna dayalı olarak, vec = * (yeni vektör (szie, 0)) yapmayı denedim; ve bu da çalıştı, ama başlatıcı listesini kullanacağım teşekkür ederim! – fenkerbb

+0

@ user1269950 Yaptıklarınız yanlış - bir bellek sızıntısı yaratır. 'new', yığında bir bellek ayırır, orada bir nesne oluşturur ve ona bir işaretçi döndürür. Yaptığınız şey, o nesnenin içeriğini üye nesnenize atamak ve daha sonra orijinal olanı unutmaktı - ancak yine de sonsuza dek ayrılmış olarak kalır. 'New' dediğinizde, her zaman döndürdüğü adresi (bir işaretçi) kaydetmeli ve sonunda bu işaretçideki 'delete' yi çağırmalısın! – Fiktik

8

vektörün kullanımı Sınıfındaki yasaldır, sorun bunu başlatmak nasıl. Eğer gerçekten bu çalışmak istiyorsanız

vec = new vector<int>(size,0); 

, o zaman vec nesne bildirmek gerektiği gibi:

vector<int> * vec; 

Ve bir yıkıcı eklemeyi unutma:

MyClass::~MyClass { 
    delete vec; 
} 

yaptılar Neden new parçacığını düşürdüğünüzde çalışıyor mu? vector ve yeni bir nesne oluşturduğunuz için, sınıfınızdaki'un üzerine yazıyorsunuz (bu, orijinali doğru bir şekilde elimine edeceğini garanti etmez).

Aslında bunu yapmanıza gerek yok. MyClass kurucusuna ulaştığınızda, vector nesnesiniz zaten başlatılmış (varsayılan kurucusu).

MyClass::MyClass(int m_size): size(m_size) { 
    vec.reserve(size); 
} 

Eğer vektör daha sonra size elemanları, sahip olmak istiyorsanız: Yorum yapanlar biri işaret ettiği gibi Nihayet

MyClass::MyClass(int m_size): size(m_size), vec(m_size, 0) 
    {} 

, sadece bellek size öğelerine ayrılmış olduğundan emin olmak istiyorsanız Vektör oluşturulduktan sonra, boyut aslında gerekli değildir. Yani size üyesinin kurtulabilirsiniz: Bu yardımcı olur

class MyClass { 
public: 
    MyClass(int m_size): vec(m_size, 0) 
     {} 

    unsigned int getSize() const 
     { return vec.size(); } 

    // ... more things... 
private: 
    vector<int> vec; 
} 

Umut.

+1

@OP - "Vektör", boyutlarını bilir, yani eğer tüm "boyut" yapmak, "vektör" içindeki elemanların sayısını takip etmekteyse, o zaman "beden" den kurtulmanızı önerir. –

+0

Çok doğru, cevabınızı yorumunuzu içerecek şekilde değiştireceğim. – Baltasarq

1
#include <vector> 
#include <iostream> 
#include <string> 
#include <typeinfo> 

using std::cout; 
using std::endl; 
using std::string; 
using std::vector; 
using std::to_string; 

class Parse 
{ 
private: 
    string   m_str; 
    vector<string> m_vec; 
public: 
    // Constructor with all defaults (1 of 4 constructors) 
    Parse(){ 
     cout << "\ncreating class with all default values\n"; 
     m_str = ""; 
     m_vec.push_back("");  
    } 

    // Constructor with all cases used 
    Parse (string   &tmp_str, 
      vector<string> tmp_vec): 

      m_str   (tmp_str), 
      m_vec   (tmp_vec) 
    { 
     cout << "Your vector contains " + to_string(m_str.size()) + " arguments\n"; 
    } 

    // Constructor with other contents given but not vector 
    Parse (string   &tmp_str): 
      m_str   (tmp_str) 
    { 
     m_vec.push_back(""); 
    } 
    // Constructor with only Vector given but not other contents 
    Parse (vector<string> tmp_vec): 
      m_vec   (tmp_vec) 
    { 
     m_str = ""; 
    } 

    string get_str_var(){return m_str;} 

    void classed_print_vector_strings() 
    { 
     for (string i : m_vec){ cout << i << " \n";} 
    } 

}; 



// rm ./class_vector; g++ class_vector.cpp -o class_vector -std=c++17; ./class_vector arg1 arg2 arg3 

int main(int argc, char *argv[]) 
{ 
    // turn **argv to a vector 
    vector<string> args(argv, argv + argc); 
    // iterate from argv through argv+argc 

    // initialize with default arguments. 
    Parse tracker1; 
    // initalize with all used arguments 
    Parse tracker2(args[0], args); 
    // initalize with only the vector 
    Parse tracker3(args); 
    // initalzie without the vector, but with another arg 
    Parse tracker4(args[0]); 

    cout << "\nTracker 1 ---------------------\n"; 
    tracker1.classed_print_vector_strings(); 
    cout << "\nTracker 2 ---------------------\n"; 
    tracker2.classed_print_vector_strings(); 
    cout << "\nTracker 3 ---------------------\n"; 
    tracker3.classed_print_vector_strings(); 
    cout << "\nTracker 4 ---------------------\n"; 
    tracker4.classed_print_vector_strings(); 


    return 0; 
} 

// rm ./class_vector; g++ class_vector.cpp -o class_vector -std=c++17; ./class_vector arg1 arg2 arg3 

// This will show you how to create a class that will give 
// you the option to initilize the class with or without 
// the vector with other arguments present and/or not present. 

// My Background. . . 
// github.com/Radicalware 
// Radicalware.net 
// https://www.youtube.com/channel/UCivwmYxoOdDT3GmDnD0CfQA/playlists 
İlgili konular