搜尋

首頁  >  問答  >  主體

c++ - 怎样可以使Score变为私有类?

以下为我练手的学生成绩查询代码段,共有两个类,一个是Score类,我想把它设为私有类,另一个为Manager类,Manager为Score类的友元。
Score.h

#include <map>
#include <string>
#include <iostream>
#ifndef SCORE_H
#define SCORE_H

struct Score
{
    friend class Manager;
    typedef std::map<std::string,double> scMap;
    typedef std::map<std::string,double>::value_type index;//pair类型
    Score():scoreMap(){}
    Score(scMap &s):scoreMap(s){}
    Score(index &i){scoreMap.insert(i);}
    void updateScore(const std::string &,double);//根据科目修改成绩
    bool insertScore(index newScore)
    {
        if((scoreMap.insert(newScore)).second==true)
            return true;
        else
        {
            std::cout<<"this project's score has existed!"<<std::endl;
            return false;
        }
    }
    double requeryScore(const std::string &)const;
    bool deleteSigleScore(const std::string &);
    std::map<std::string,double> scoreMap;
};
#endif

Score.cpp

#include "StdAfx.h"
#include <iostream>
#include "Manager.h"
#include "Score.h"

void Score::updateScore(const std::string &pro,double newScore)
{
    if(scoreMap.count(pro))
    {
        scoreMap[pro]=newScore;
    }
    else
    {
        std::cout<<"This student's "<<pro<<"don't exist!"<<std::endl;
    }
}

double Score::requeryScore(const std::string & sc)const
{
    if(scoreMap.count(sc))
    {
        double newScor=(*(scoreMap.find(sc))).second;
        return newScor;
    }
    else
    {
        std::cout<<"This student's "<<sc<<"don't exist!"<<std::endl;
        return 0;
    }
}

bool Score::deleteSigleScore(const std::string &spro)
{
    if(scoreMap.erase(spro))
    {
        return true;
    }
    else
        return false;
}

Manager.h

#pragma once
#include <map>
#include <string>
#include <iostream>
#include "Score.h"

#ifndef MANAGER_H
#define MANAGER_H

class Manager
{
    typedef std::map<std::string,Score> studentMap;
public:
    //只添加学生,不添加成绩
    bool add(const std::string &);
    //同时添加姓名以及成绩
    bool add(const std::string &,Score::index);
    bool add(const std::string &,Score::scMap &);
    /*void insertScore(const std::string &,*/
    bool deleteStu(const std::string &);
    bool deleteScore(const std::string &,const std::string &);
    bool updateName(const std::string &,const std::string &);
    bool updateScore(const std::string &,const std::string &,double);
    double querySingleScore(const std::string &,const std::string &);
    std::map<std::string,double> queryAllScore(const std::string &);
    
private:
    std::map<std::string,Score> stuMap;
};
#endif

Manager.cpp

#include "StdAfx.h"
#include "Manager.h"
#include <iostream>
#include <utility>
#include <iostream>
#include <map>

bool Manager::add(const std::string &sname)
{
    if(stuMap.count(sname))
    {
        std::cout<<sname<<"has existed"<<std::endl;
        return false;
    }
    else
    {
        std::pair<std::string,Score> newP;
        newP.first=sname;
        newP.second=Score();
        stuMap.insert(newP);
    }
    
}

bool Manager::add(const std::string &sname,Score::index scor)
{
    if(stuMap.count(sname))
    {
        stuMap[sname].insertScore(scor);
        return true;
    }
    else
    {
        stuMap.insert(std::make_pair(sname,Score(scor)));
        return true;
    }
}

bool Manager::add(const std::string &sname,Score::scMap &sCore)
{
    if(stuMap.count(sname))
    {
        std::cout<<sname<<"has existed"<<std::endl;
        return false;
    }
    else
    {
        stuMap.insert(std::make_pair(sname,sCore));
        return true;
    }
}

bool Manager::deleteStu(const std::string &sname)
{
    if(stuMap.erase(sname))
    {
        std::cout<<sname<<"has delelted"<<std::endl;
        return true;
    }
    else
    {
        std::cout<<sname<<"delete fail"<<std::endl;
        return false;
    }
}

bool Manager::deleteScore(const std::string &sname,const std::string &project)
{
    studentMap::iterator stu=stuMap.find(sname);
    if(stu!=stuMap.end())
    {
        return (stu->second).deleteSigleScore(project);
    }
    else
    {
        return false;
    }
}

bool Manager::updateName(const std::string &oldName,const std::string &newName)
{
    studentMap::iterator iter=stuMap.find(oldName);
    if(iter!=stuMap.end())
    {
        add(newName,iter->second.scoreMap);
        return true;
    }
    else
    {
        std::cout<<oldName<<"did not existed"<<std::endl;
        return false;
    }
}

bool Manager::updateScore(const std::string &stuName,const std::string &projName,double newScore)
{
    studentMap::iterator iter=stuMap.find(stuName);
    if(iter!=stuMap.end())
    {
        iter->second.updateScore(projName,newScore);
        return true;
    }
    else
        return false;
}

double Manager::querySingleScore(const std::string &sname,const std::string &proj)
{
    studentMap::iterator iter=stuMap.find(sname);
    /*if(iter!=stuMap.end())
    {*/
        double newScor=iter->second.requeryScore(proj);
        return newScor;
    /*}*/ 
}

std::map<std::string,double> Manager::queryAllScore(const std::string &sname)
{
    studentMap::iterator iter=stuMap.find(sname);
    return iter->second.scoreMap;
}

主程序

#include "stdafx.h"
#include "Manager.h"
#include <iostream>
#include <map>
#include <utility>

static enum choice
{
    Query,
    Delete,
    Update,
    Add
};

Manager manager;

void queryN()
{
    std::cout<<"*******************"<<std::endl;
    std::cout<<"Please enter the name you want to query:"<<std::endl;
    std::string studentName,projectName;
    if(std::cin>>studentName)
    {
        std::cout<<"*******************"<<std::endl;
        std::cout<<"Please enter the project name you want to query"<<std::endl;
        while(std::cin>>projectName)
        {
            double tempScore=manager.querySingleScore(studentName,projectName);
            std::cout<<studentName<<"'s "<<projectName<<"is "<<tempScore<<std::endl;
        }
    }
    std::cin.clear();
}

void cmdDelete()
{
    //delete student
    std::cout<<"*******************"<<std::endl;
    std::cout<<"What's info do you want to delete ?(0:Student,1:Student's score)"<<std::endl;
    int i;
    std::string nameDele,projDele;
    std::cin>>i;
    switch(i)
    {
    case 0:
        std::cout<<"*******************"<<std::endl;
        std::cout<<"Please enter the name the student you want to delete"<<std::endl;
        while(std::cin>>nameDele)
        {
            if(manager.deleteStu(nameDele))
                std::cout<<nameDele<<"deleted"<<std::endl;
            else
                std::cout<<nameDele<<"deleted fail"<<std::endl;
        }
        break;
    case 1:
        std::cout<<"*******************"<<std::endl;
        std::cout<<"Please enter the name the student you want to delete"<<std::endl;
        while(std::cin>>nameDele)
        {
            std::cout<<"Please enter the project that you want to delete"<<std::endl;
            while(std::cin>>projDele)
            {
                if(manager.deleteScore(nameDele,projDele))
                    std::cout<<nameDele<<"'s"<<projDele<<"succeed"<<std::endl;
                else
                    std::cout<<nameDele<<"'s"<<projDele<<"fail"<<std::endl;
            }
        }
        break;
    }
    std::cin.clear();
}

void updateInfo()
{
    std::cout<<"*******************"<<std::endl;
    std::cout<<"Please enter what info do you want to update?(0:stdudent's name 1:score"<<std::endl;
    int i;
    std::string queryName,newName,projName;
    double newScore;
    std::cin>>i;
    switch(i)
    {
    case 0:
        std::cout<<"*******************"<<std::endl;
        std::cout<<"Please enter the name you want to update"<<std::endl;
        std::cin>>queryName;
        std::cout<<"*******************"<<std::endl;
        std::cout<<"Please enter new name"<<std::endl;
        std::cin>>newName;
        if(manager.updateName(queryName,newName))
        {
            std::cout<<"*******************"<<std::endl;
            std::cout<<queryName<<" has changed to "<<newName<<std::endl;
        }
        else
        {
            std::cout<<"*******************"<<std::endl;
            std::cout<<"change fail"<<std::endl;
        }
        break;
    case 1:
        std::cout<<"*******************"<<std::endl;
        std::cout<<"Please enter the name you want to update"<<std::endl;
        std::cin>>queryName;
        std::cout<<"*******************"<<std::endl;
        std::cout<<"Please enter project name you want to update"<<std::endl;
        std::cin>>projName;
        std::cout<<"*******************"<<std::endl;
        std::cout<<"Please enter the new score "<<std::endl;
        std::cin>>newScore;
        if(manager.updateScore(queryName,projName,newScore))
        {
            std::cout<<"*******************"<<std::endl;
            std::cout<<queryName<<"'s"<<projName<<" has changed to "<<newScore<<std::endl;
        }
        else
        {
            std::cout<<"*******************"<<std::endl;
            std::cout<<"change fail"<<std::endl;
        }
        break;
    }
    std::cin.clear();
}

void cmdAdd()
{
    std::string newName,newProj;
    double newScore;
    do{
        std::cout<<"*******************"<<std::endl;
        std::cout<<"Please enter the new name,enter 'q' to finish"<<std::endl;
        std::cin>>newName;
        std::cout<<"*******************"<<std::endl;
        std::cout<<"Please enter the new project"<<std::endl;
        while(std::cin>>newProj)
        {
            std::cout<<"*******************"<<std::endl;
            std::cout<<"Please enter the new score"<<std::endl;
            if(std::cin>>newScore)
            {
                manager.add(newName,std::make_pair(newProj,newScore));
            }
        }
    }while(std::cin&&newName!="q");
}

int _tmain(int argc, _TCHAR* argv[])
{
    int choiceInt;
    do{
    std::cout<<"Please choose the function you want to do:"<<std::endl;
    std::cout<<"*******************"<<std::endl;
    std::cout<<"0:Query"<<std::endl<<"1:Delete"<<std::endl<<"2:Update"<<std::endl<<"3:Add"<<std::endl;
    
    std::cin>>choiceInt;
    
        switch(choiceInt)
    {
    case 0:
        queryN();
        std::cin.clear();
        break;
    case 1:
        cmdDelete();
        std::cin.clear();
        break;
    case 2:
        updateInfo();
        std::cin.clear();
        break;
    case 3:
        cmdAdd();
        std::cin.clear();
        break;
    }
    }while(std::cin);
    return 0;
  }

我是把Manager的数据成员定义成string-Score的Map容器,但是我想把Score设为私有类只有Manager类可访问,这样Score就不能作为容器的元素,设为指针?也不行啊。大神可以指导一下么?

天蓬老师天蓬老师2807 天前403

全部回覆(2)我來回復

  • 迷茫

    迷茫2017-04-17 13:17:33

    把Score類別的聲明當作private成員放在Manager類別的聲明裡:

    //Manager.h
    class Manager{
    public:
        //some public declarations
    private:
        class Score{
        public:
        //public members
        private:
        //private members go here
        };
        //std::map<std::string, Score*> someMap;
        typedef std::shared_ptr<Score> ScorePtr;
        std::map<std::string, ScorePtr> anotherMap;
    };
    

    這樣你的Manager類別裡的Score類別就是私有的,當別人試圖實例化一個Score編譯器會報錯:

    Manager::Score score;//error, class Manager::Score is private

    然後每次需要對這個Map進行insert的時候,你用std::make_shared包上一層傳進去。

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-17 13:17:33

    你把Score類別移到Manager類別裡面不就完了。

    回覆
    0
  • 取消回覆