用于双精度和指针C++的容器
Container for double and a pointer C++?
我有两个问题。1. 我是否使用最有效的容器来盛放[双精度,物体*]?2. 如果地图是我应该使用的选项,那么一旦物体进入地图,我该如何访问它?我正在尝试在函数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号的数据类型选择。您使用的是双精度数,这是一个浮点数,但您只需要整数值,因此使用整数类型会更明智。
容器的选择取决于您计划如何访问和修改容器中的数据。需要考虑的一些关键特征是:
您是否需要能够以随机顺序访问容器中的元素?即。按 ID 查找元素?对此有益的容器是映射、unordered_map、矢量。列表对此不利,因为您必须遍历列表才能找到所需的元素。
您是否需要能够以某种预定顺序(例如.key顺序(遍历值?对此有益的容器是映射,向量,各种列表类型。
您是否需要能够在任何给定位置插入元素?还是只在最后插入就足够了?如果是前者那么地图,unordered_map,列表都很好。如果是后者,那么向量是好的。
将使用哪种类型的键来查找值?您可以通过整数查找向量中的条目,但是如果您有字符串,则需要使用映射或unordered_map。
如果键是数字 - 列表是否稀疏?即。序列中会有很大的间隙吗?如果是,则向量吸引力较小,因为可能会浪费大量内存。
您的特征似乎是:
- 您需要能够按 ID 查找客户
- 您需要能够循环访问列表以打印出数据库。我不确定是否要求按顺序这样做,但让我们假设它是。
- 看起来好像您在列表末尾添加了新条目。
- 键是整数
- 我不确定该列表是否会稀疏。如果您从中间删除大量客户,则可能会有间隙。
如果不是最后一点,矢量实际上可能是比地图更好的选择。矢量价格便宜,并且对于您将使用的大多数操作都具有高性能。
无论如何,如果您根据您对应用程序的了解确定映射是最好的,那么当您循环访问映射时,迭代器指向容器的value_type,在映射的情况下,容器的类型为 std::p air,其中 K 是键类型,V 是值类型。此值类型存储键和值,您可以使用"第一个"和"第二个"成员访问它们。
for (it = cDatabase.begin(); it != cDatabase.end(); it++) {
cout << "Key: " << it->first << endl;
cout << it->second->getFirstName() << endl;
}
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 调整大小后指向元素值的指针unordered_map有效?
- 正在将指针转换为范围
- 使用指向成员的指针将成员函数作为参数传递
- 将OpenCV C++重写为EmguCV C#-如何使用指针
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错