2015-02-26 7 views
6

मैं अपने क्लास क्लास प्रकार के स्टॉक के लिए एक स्मृति याद करता हूं जो बेस क्लास उपकरण से विरासत में मिला है, जब मैं अपने सरणी के दूसरे तत्व तक पहुंचने का प्रयास करता हूं, तो यह त्रुटि फेंकता है। हालात ठीक हैं जब मैं अपनी नई सरणी आकार 1क्यों मैं अपने लूप में गतिशील आवंटित स्मृति तक नहीं पहुंच सकता?

#include <iostream> 
#include <fstream> 
#include <string> 
using namespace std; 

class Instrument{ 

public: 
    virtual void display(){} 
    virtual void output(){} 
    virtual void readFile(){} 
    virtual ~Instrument(){} 
}; 
class Stock : 
    public Instrument{ 
public: 
    Stock(){ 

    } 
    virtual void input(){ 
     cout << "This is stock, please input its information: "; 
     cin >> name >> bidPrice >> askPrice >> lastPrice >> issueExchange; 
    } 
    virtual void display(){ 
     cout <<"This is to display stock: "<< name << " " 
      << bidPrice << " " 
      << askPrice << " " 
      << lastPrice << " " 
      << issueExchange << " " 
      << endl; 
    } 
    virtual void output(){ 
     ofstream myfile; 
     myfile.open("Stock.txt", ios::out | ios::app); 
     if (myfile.is_open()){ 
      myfile << "This is a stock: " 
       << name << " " 
       << bidPrice << " " 
       << askPrice << " " 
       << lastPrice << " " 
       << issueExchange << " " 
       << endl; 
     } 
     else cout << "Unable to open file"; 
    } 
    virtual void readFile(){ 
     string line; 
     ifstream myfile("Stock.txt"); 
     cout << "\nThis is file stored\n"; 
     if (myfile.is_open()) 
     { 
      while (getline(myfile, line)) 
      { 
       cout << line << '\n'; 
      } 
      myfile.close(); 
     } 
    } 
    virtual ~Stock(){} 
private: 
    char name[13]; 
    double bidPrice; 
    double askPrice; 
    double lastPrice; 
    int issueExchange; 

}; 


int main(){ 

    const int N = 5;//it works fine if I use N=1; 
    Instrument *pBase = NULL; 
    pBase = new Stock[N]; 

    for (int i = 0; i < N; i++){ 
     pBase[i].input();// here throws an exception and ends the program 
     pBase[i].display(); 
     pBase[i].output(); 
    } 
    pBase[N - 1].readFile(); 
    delete[] pBase; 

    system("pause"); 
    return 0; 

} 
+0

@GermaineJason यह जावा या सी # नहीं है। वस्तुएं हैं, और एक एनपीई मौजूद नहीं है। – deviantfan

+0

दिलचस्प, मुझे त्रुटि दिखाई देती है, और मुझे आश्चर्य है कि मैंने इसे पहले कभी नहीं देखा है। यह लगभग टुकड़ा करने की तरह है, लेकिन यह अलग है। @GermaineJason सरणी में 5 वस्तुएं हैं। –

+0

@MooingDuck, यह स्ट्रिंग से char [13] में बदल दिया गया है, क्या आप मेरा # शामिल Leewis

उत्तर

7

बहुरूपता और सूचक अंकगणित मिश्रित नहीं है, क्योंकि एक सरणी के भीतर वस्तुओं की व्यवस्था सबसे व्युत्पन्न आकार पर निर्भर करता है, और बहुरूपता है कि जानकारी खो देता है। कि array का उपयोग कर सूचक मान sizeof (Derived) से आगे बढ़ रहे हैं, लेकिन सूचक अंकगणित p का उपयोग कर sizeof (Base) से आगे बढ़ रहा है और नहीं मिल

Derived array[2]; 
Base* p = array; 

printf("%p\n", &array[0]); 
printf("%p\n", p); 
printf("%p\n", &array[1]); 
printf("%p\n", p + 1); 

printf("%z\n", sizeof (array[0])); 
printf("%z\n", sizeof (*p)); 

नोट: गतिशील आवंटन एक रेड हेरिंग, आप के साथ एक ही समस्या देख सकते हैं असली वस्तुओं।

आम तौर पर आप पॉइंटर अंकगणितीय के साथ संयुक्त Base* के बजाय Base* की सरणी का उपयोग करके इसे ठीक कर देंगे।

Base* pp[2]; 
for(auto& elem : array) pp[&elem - array] = &elem; 

printf("%p\n", &array[1]); 
printf("%p\n", pp[1]); 

// use (*pp[1]) or pp[1]->whatever 

एक अन्य विकल्प एक उद्देश्य यह है कि मूल प्रकार याद है उपयोग करने के लिए है:

Derived* allocated = new Derived[N]; 
std::function<Base& (int)> poly = [allocated](int i){ return allocated[i]; }; 

और p[i]

लेकिन चेतावनी के बजाय poly(i) उपयोग करते हैं, तुम क्या नहीं कर सकते delete [] &poly(0); क्योंकि delete[] या तो बहुरूपी नहीं है ।

std::unique_ptr<Derived[]> और std::bind का उपयोग करके, जब कोई एक्सेसर ऑब्जेक्ट अंततः दायरे से बाहर हो जाता है तो स्वचालित डेलोकेशन की व्यवस्था कर सकता है।

+3

सटीक होने पर, यह उत्तर स्पष्टीकरण में थोड़ा सा कमी है, है ना? –

+0

@MooingDuck: बेहतर? –

+0

हां, वह बिंदु, लेकिन मेरा असाइनमेंट मुझे एक ही समय में बहुरूपता और सरणी का उपयोग करने के लिए कहता है, मैं इंट्रूमेंट * पी [एन], और पी [i] तक पहुंचने का प्रयास करता हूं, लेकिन यह यहां काम नहीं करता है। यह नया तरीका है जिसकी मैंने कोशिश की – Leewis

1

हालांकि श्रीबेन की विधि बिल्कुल सही है, लेकिन मुझे पूरी तरह से लगता है कि उसका सी ++ और मेरा सी ++ एक ही भाषा नहीं है, वह यहां कुछ अजीब चीज़ों को मिला रहा है, इस प्रकार उनके विचार के अनुसार, मैंने अपने कोड को संशोधित करने की कोशिश की इस।

#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 
#include <memory> 
using namespace std; 

class Instrument{ 

public: 
    virtual void display() = 0; 
    virtual void output() = 0; 
    virtual void readFile() = 0; 
    virtual ~Instrument(){}; 
}; 
class Stock : 
    public Instrument{ 
public: 
    Stock(){ 
     cout << "This is stock, please input its information: "; 
     cin >> name >> bidPrice >> askPrice >> lastPrice >> issueExchange; 
    } 
    virtual void display(){ 
     cout << "This is to display stock: " << name << " " 
      << bidPrice << " " 
      << askPrice << " " 
      << lastPrice << " " 
      << issueExchange << " " 
      << endl; 
    } 
    virtual void output(){ 
     ofstream myfile; 
     myfile.open("Stock.txt", ios::out | ios::app); 
     if (myfile.is_open()){ 
      myfile << "This is a stock: " 
       << name << " " 
       << bidPrice << " " 
       << askPrice << " " 
       << lastPrice << " " 
       << issueExchange << " " 
       << endl; 
     } 
     else cout << "Unable to open file"; 
    } 
    virtual void readFile(){ 
     string line; 
     ifstream myfile("Stock.txt"); 
     cout << "\nThis is file stored\n"; 
     if (myfile.is_open()) 
     { 
      while (getline(myfile, line)) 
      { 
       cout << line << '\n'; 
      } 
      myfile.close(); 
     } 
    } 
    virtual ~Stock(){} 
private: 
    string name; 
    double bidPrice; 
    double askPrice; 
    double lastPrice; 
    int issueExchange; 

}; 
class Option : 
    public Instrument{ 
public: 
    Option(){ 
     cout << "This is option, please input its information: "; 
     cin >> name >> uname >> bidPrice >> askPrice >> lastPrice >> contractSize >> exp; 
    } 
    virtual void display(){ 
     cout << "This is to display option: " 
      << name << " " 
      << uname << " " 
      << bidPrice << " " 
      << askPrice << " " 
      << lastPrice << " " 
      << contractSize << " " 
      << exp << " " 
      << endl; 
    } 
    virtual void output(){ 
     ofstream myfile; 
     myfile.open("Option.txt", ios::out | ios::app); 
     if (myfile.is_open()){ 
      myfile << "This is an option: " 
       << name << " " 
       << uname << " " 
       << bidPrice << " " 
       << askPrice << " " 
       << lastPrice << " " 
       << contractSize << " " 
       << exp << " " 
       << endl; 
     } 
     else cout << "Unable to open file"; 
    } 
    virtual void readFile(){ 
     string line; 
     ifstream myfile("Option.txt"); 
     cout << "\nThis is file stored\n"; 
     if (myfile.is_open()) 
     { 
      while (getline(myfile, line)) 
      { 
       cout << line << '\n'; 
      } 
      myfile.close(); 
     } 
    } 
    virtual ~Option(){} 
private: 
    string name; 
    string uname; 
    double bidPrice; 
    double askPrice; 
    double lastPrice; 
    int contractSize; 
    double exp; 
}; 
class Future : 
    public Instrument{ 
public: 
    Future(){ 
     cout << "This is option, please input its information: "; 
     cin >> name >> uname >> bidPrice >> askPrice >> lastPrice >> contractSize >> tickSize >> contractMonth; 
    } 
    virtual void display(){ 
     cout << "This is to display option: " 
      << name << " " 
      << uname << " " 
      << bidPrice << " " 
      << askPrice << " " 
      << lastPrice << " " 
      << contractSize << " " 
      << tickSize << " " 
      << contractMonth << " " 
      << endl; 
    } 
    virtual void output(){ 
     ofstream myfile; 
     myfile.open("Future.txt", ios::out | ios::app); 
     if (myfile.is_open()){ 
      myfile << "This is a future: " 
       << name << " " 
       << uname << " " 
       << bidPrice << " " 
       << askPrice << " " 
       << lastPrice << " " 
       << contractSize << " " 
       << tickSize << " " 
       << contractMonth << " " 
       << endl; 
     } 
     else cout << "Unable to open file"; 
    } 
    virtual void readFile(){ 
     string line; 
     ifstream myfile("Future.txt"); 
     cout << "\nThis is file stored\n"; 
     if (myfile.is_open()) 
     { 
      while (getline(myfile, line)) 
      { 
       cout << line << '\n'; 
      } 
      myfile.close(); 
     } 
    } 
    virtual ~Future(){} 
private: 
    string name; 
    string uname; 
    double bidPrice; 
    double askPrice; 
    double lastPrice; 
    int contractSize; 
    int tickSize; 
    int contractMonth; 
}; 

int main(){ 

    int N = 20; 
    //shared_ptr<Instrument> pBase[N]; 
    vector<shared_ptr<Instrument>> pBase(N); 
    int i = 5; 
    for (i = 0; i < N; i++) pBase[i] = make_shared<Stock>(); 
    for (i = 0; i < N; i++){ 
     pBase[i]->display(); 
     pBase[i]->output(); 
    } 
    pBase[N - 1]->readFile(); 

    for (i = 0; i < N; i++) pBase[i] = make_shared<Option>(); 
    for (i = 0; i < N; i++){ 
     pBase[i]->display(); 
     pBase[i]->output(); 
    } 
    pBase[N - 1]->readFile(); 

    for (i = 0; i < N; i++) pBase[i] = make_shared<Future>(); 
    for (i = 0; i < N; i++){ 
     pBase[i]->display(); 
     pBase[i]->output(); 
    } 
    pBase[N - 1]->readFile(); 

    system("pause"); 
    return 0; 

} 
0

tl; डॉ जवाब: एक आधार वर्ग सूचक (pBase) के उपवर्ग सरणी (Stock[N]) पूरे नहीं करेंगे। या तो सीधे Stock* उपयोग करें, या बजाय संकेत की एक सरणी बनाएँ:

auto arr = new Stock*[N]; 
for (int i = 0; i < N; i++) { 
    arr[i] = new Stock(); 
} 

// unrelated but suggested: C++11 unique_ptr is recommended: 
vector<unique_ptr<Stock>> v(N); 

विस्तृत कारण हैं:

1) सरणी ब्रैकेट ऑपरेटर एक वाक्यात्मक चीनी है: a[b] -> *(a + b);

2) सूचक गणित, बहुरूपी नहीं है यह हमेशा स्थिर प्रकार पर आधारित है: जब तक sizeof(Instrument) != sizeof(Stock)

pBase[i] -> *(pBase+i) -> *(pBase*)((char*)pBase + sizeof(Stock) * i); 

4):)

pBase[i] -> *(pBase+i) -> *(pBase*)((char*)pBase + sizeof(Instrument) * i); 

3 हालांकि यह है, आप क्या चाहते हैं , तुम मुसीबत में हो।

+0

मैं करता हूं, मेरा जवाब देखें, वेक्टर > पीबीएस (एन); – Leewis

संबंधित मुद्दे