簡體   English   中英

雙精度和指針C ++的容器?

[英]Container for double and a pointer C++?

我有兩個問題。 1.我是否在使用最有效的容器來容納[double,object *]? 2.如果我應該使用Map,那么一旦對象指向地圖,我又如何訪問它呢? 我正在嘗試在函數printMap()中打印地圖而沒有任何運氣。 嘗試了多種變體。

  void printMap() {  //How do i verify what's in my map??!!!!!!!!!!!!!!!!!!!!!!!!
            for (it = cDatabase.begin(); it != cDatabase.end(); it++)
            {
                double temp = 0;
                temp = it->first;
                cout << "Key: " << it->first << endl;
                cout << cDatabase[it->first]->getFirstName();
            }
        }

提前致謝

埃里克

PS:我包括了整個.cpp文件。

//Erik Plachta
//Purpose: Creating a Customer Relations Management system. Should be able to create employees and customers that can we stored within a database.

#include<fstream>      //for customer database
#include<map>          //for customer database
#include<sstream>       //for customer database
#include<stdlib.h>        //for customer database

#include <iostream>
using namespace std;

///////////////////////////////////////////////////////////////////////////////
/////EMPLOYEE///////////EMPLOYEE////////////EMPLOYEE/////////EMPLOYEE//////////
///////////////////////////////////////////////////////////////////////////////
class Employee {

    string firstName, lastName, password, username;  //used to create unique sessions for each user. Login info
    bool manager;   //If manager, will have spec privlages within the app.
    int sessionTime; //used to record login/logoff time. 

    public:
        Employee(string FN, string LN, string pass, string userN) { //first name, last name and pass
           setName(FN, LN);
           setPassword(pass); 
           setUsername(userN);
        }

        string getName() {
            string fullName = firstName + " " + lastName;
            return fullName;
        }

        bool confirmPassword(string pass) {  //used to test if true or false without giving program the password back.
            bool status = false; 
            if (pass == password) {
                status = true;
            } 
            return status;
        }

        bool confirmUsername(string userN) {
            bool status = false;
            if (userN == username) {
                status = true;
            }
            return status;
        }

    private:
        void setName(string FN, string LN) {
            firstName = FN;
            lastName = LN;}

        void setPassword (string pass) {
            password = pass;
        }

        void setUsername(string userN) {
            username = userN;
        }
};


void printEmployee(Employee employee) {  //this is confirming the password entered was the same in the database. there will be a private database holding user login info
    bool status;
    cout <<"Name: " << employee.getName() << endl;
    status = employee.confirmPassword("123456"); 
    cout << "Password test: " << status << endl;
    status = employee.confirmUsername("EPlachta");
    cout << "Username test: " << status << endl;
}

///////////////////////////////////////////////////////////////////////////////
///CUSTOMER////////////CUSTOMER/////////CUSTOMER/////CUSTOMER//////CUSTOMER////
///////////////////////////////////////////////////////////////////////////////
class Customer {
    string firstName, lastName, phoneNumber, eMail; 
    double customerNumber;
    public: 
        Customer (string FN, string LN, string phoneN, string EM, double customerNum) {
            setName(FN, LN);   
            setPhoneNumber(phoneN);
            setEmail(EM);
            setCustomerNumber(customerNum);
        }

        string getFirstName() {
            return firstName;
        }

        string getLastName() {
            return lastName;
        }

        string getPhoneNumber() {
            return phoneNumber;
        }

        string getEmailAddress(){
            return eMail;
        }

        double getCustomerNumber() {
            return customerNumber;
        }

        void printCustomer() {
            cout << "First Name: " << getFirstName() << endl;
            cout << "lastName: " << getLastName() << endl;
            cout << "Email: " << getEmailAddress() << endl;
            cout << "PhoneNumber: " << getPhoneNumber() << endl;
            cout <<"CustomerNumber: "<< getCustomerNumber() << endl;
        }

    private: 
        void setName(string FN, string LN) {
            firstName = FN;
            lastName = LN;
        }   

        void setPhoneNumber(string phoneN) {
            phoneNumber = phoneN;
        }

        void setEmail(string EM) {
            eMail = EM;
        }

        void setCustomerNumber(double customerNum) {
            customerNumber = customerNum;
        }
} ;

//print customer is uptop here for now. Will be put into it's own class


///////////////////////////////////////////////////////////////////////////////
///CUSTOMER DATABASE///////////////CUSTOMER DATABASE///////CUSTOMER DATABASE///
///////////////////////////////////////////////////////////////////////////////

class CustomerDatabase {
    double customerNumbers; // used to increment from 100000 - 99999. An easy way to give out new numbers and to prevent duplicates.
    map <double, Customer*> cDatabase;
    map <double, Customer*>:: iterator it;

    public:
        CustomerDatabase() { 
            customerNumbers = 100000;
            loadCustomers();
        }
        void printMap() {  //How do i verify what's in my map??!!!!!!!!!!!!!!!!!!!!!!!!
            for (it = cDatabase.begin(); it != cDatabase.end(); it++)
            {
                double temp = 0;
                temp = it->first;
                cout << "Key: " << it->first << endl;
                cout << cDatabase[it->first]->getFirstName();
            }
        }
        double newCustomerNumber() {   // Used to generate unique customer IDs easily. 
            double customerNumberHolder = customerNumbers;
            customerNumbers++;
            return customerNumberHolder;
        }     

        bool saveCustomer(double customerN, Customer *c) { //saves customer to database once created  **NOT WORKING YET
            addCustomer(customerN, c);
            ofstream databaseFile;  //filestream local for output
            bool saveCustomer = false;
            if (checkForCustomerNumber(customerN) != false) { // if the customer isn't in the database
                ostringstream stream; // USED TO MAKE AN INT INTO A STRING. Local stream to keep clear
                stream << c->getCustomerNumber();
                databaseFile.open ("database/databaseFile.csv", ios::app);
                string customerHolder = c->getFirstName() + "," + c->getLastName() + "," + c->getPhoneNumber() + "," + c->getEmailAddress() + ","  + stream.str()  + "\n"  ;
                databaseFile << customerHolder;
                databaseFile.close();
                saveCustomer = true;
            }
            cout << "Customer saved Status: " << saveCustomer << endl;
            return saveCustomer;
        }        

        bool addCustomer(double customerN, Customer *c) {
            bool addCustomer = false;
            cDatabase[customerN] =  c;
            return addCustomer;

        }

    private:

        bool loadCustomers() {
            string firstN, lastN, phoneN, emailA;
            double customerN;
            const int FIRSTNAME = 0;
            const int LASTNAME = 1;
            const int PHONENUMBER = 2;
            const int EMAIL = 3;
            const int CUSTOMERNUMBER = 4;
            //skipped 5 because every new line also runs through the while loop. 
            const int ADDTODATABASE = 5;
            ifstream databaseFile; //file-stream local for input
            databaseFile.open ("database/databaseFile.csv", ios::in);
            string line = "";
            int i = 0;
            double loadedCustomers = 0; //used to keep track of customer loaded.
            while( getline(databaseFile, line, ',')) {
                if (i == FIRSTNAME) {
                    firstN = line;
                    i++;
                }  else if (i == LASTNAME) {
                    lastN = line;
                    i++;
                } else if (i == PHONENUMBER) {
                    phoneN = line;
                    i++;
                } else if (i == EMAIL) {   
                    emailA = line;
                    i++;
                } else if (i == CUSTOMERNUMBER) {
                    double customerNumb = atoi(line.c_str()); 
                    customerN = customerNumb;
                    Customer c(firstN, lastN, phoneN, emailA, customerN);
                    Customer *holder;
                    holder = &c;
                    addCustomer(c.getCustomerNumber(), holder);
                    i = 0; //resetting for next line.
                }
//this is how i was saving a customer to the database. I dont' need to save when loading customers. saving code incase needed//                saveCustomer(c.getCustomerNumber(), c);     
            }
            databaseFile.close();
        }

        bool checkForCustomerNumber(double customerN) { //If ID # is within the database, it will return a true that the ID exists
            bool customerNumberMatch = false;
            if((cDatabase.find(customerN)) != (cDatabase.end())) { //if the customer number is the key for the map, it will not reach the end. therein the customer is already in the database
                customerNumberMatch = true;
                customerNumbers++;
            }
            cout << "C. Number Match Satus: " << customerNumberMatch << endl;
            return customerNumberMatch;
        }
};


///////////////////////////////////////////////////////////////////////////////
//MAIN////////////////MAIN/////////////MAIN////////////////MAIN/////////MAIN///
///////////////////////////////////////////////////////////////////////////////

int main() {
    //CUSTOMER DATABASE CREATION
    CustomerDatabase customerDatabase;   //creating database
    ////CUSTOMER
    Customer JT("Johnny", "Tester", "989-123-4567", "johnnyTester@gmail.com", customerDatabase.newCustomerNumber());    // used to create a test customer

    Customer Test ("This", "is", "a", "test", 100000);
    Customer TT("Timmy", "Tester", "989-989-9898", "Erik@itsaTest.com", customerDatabase.newCustomerNumber());
    //CUSTOMER DATABASE USED
    Customer *holder;
    holder = &JT;
    customerDatabase.saveCustomer(holder->getCustomerNumber(), holder);
    holder = &TT;
    customerDatabase.saveCustomer(holder->getCustomerNumber(), holder);
    holder = &Test;
    customerDatabase.saveCustomer(holder->getCustomerNumber(), holder);
    customerDatabase.printMap();
    //EMPLOYEE
    Employee EP ("Erik", "Plachta", "123456", "EPlachta");                        //creating test employee
  //  printEmployee(EP);                                                            //making sure employee can login / was created correctly.      

    cin.get();
    return 0;
}

//Customer class looks at database for an ID it wants to use, 

在開始選擇容器之前,我想談談ID號數據類型的選擇。 您使用的是雙精度數,這是一個浮點數,但是您只需要整數值,因此使用整數類型會更明智。

容器的選擇取決於您計划如何訪問和修改容器中的數據。 要考慮的一些關鍵特征是:

  1. 您是否需要能夠以隨機順序訪問容器中的元素? 就是 通過ID查找元素? 對此有利的容器是map,unordered_map,vector。 列表對此不利,因為您必須遍歷列表才能找到所需的元素。

  2. 您是否需要能夠以某種預定順序(例如鍵順序)遍歷值? 對此有利的容器是地圖,向量,各種列表類型。

  3. 您是否需要能夠在任何給定位置插入元素? 還是僅在末尾插入就足夠了? 如果前者然后映射,unordered_map,列表是好的。 如果是后者,則向量是好的。

  4. 什么類型的鍵將用於查找值? 您可以按整數查找向量中的條目,但是,例如,如果有字符串,則需要使用map或unordered_map。

  5. 如果鍵為數字-列表是否稀疏? 就是 序列中會有很大的缺口嗎? 如果是,則矢量的吸引力較小,因為可能會浪費大量內存。

您的特征似乎是:

  1. 您需要能夠通過ID查找客戶
  2. 您需要能夠遍歷列表以打印出數據庫。 我不確定是否需要按順序進行操作,但讓我們假設是。
  3. 好像您要在列表末尾添加新條目。
  4. 鍵是整數
  5. 我不確定列表是否會稀疏。 如果您從中間刪除許多客戶,則可能存在差距。

如果不是最后一點,向量實際上可能比地圖更好。 向量很便宜,並且對於您將要使用的大多數操作都具有高性能。

無論如何,如果您根據對應用程序的了解確定地圖是最佳的,則當您遍歷地圖時,迭代器指向容器的value_type,在地圖的情況下,容器的類型為std: :pair,其中K是鍵類型,V是值類型。 此值類型存儲鍵和值,您可以使用“第一”和“第二”成員進行訪問。

for (it = cDatabase.begin(); it != cDatabase.end(); it++) {
    cout << "Key: " << it->first << endl;
    cout << it->second->getFirstName() << endl;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM