protobuf c++的函数和双计数问题



代码如下:

#include <iostream>
#include <fstream>
#include "Students.pb.h"

class IRepository {
virtual void Open() = 0; // binary decerialization 
virtual void Save() = 0; // binary serialization
};

class IMethods {
virtual double GetAverageScore(const FullName& name) = 0;
virtual std::string GetAllInfo(const FullName& name) = 0;
virtual std::string GetAllInfo() = 0;
};
StudentsGroup group1;

class StudentGroup : public IRepository, public IMethods
{
public:
void Open() override
{
std::fstream in("D:GeekBrains CPPdiff moments 7studentsgroup.bin", std::ios_base::binary);
group1.ParseFromIstream(&in);
if (!group1.ParseFromIstream(&in))
{
std::cout << "Open error!" << std::endl;
}

}
void Save() override
{
std::fstream out("D:GeekBrains CPPdiff moments 7studentsgroup.bin", std::ios_base::binary);
group1.SerializeToOstream(&out);

}
double GetAverageScore(const FullName& name) override
{
int i = 0;
double average;
for (const auto& student : group1.sinfo())
{
if (student.sname().surname() == name.surname() && student.sname().name() == name.name())
{
std::cout << "Average score is: " << student.averagemark();
average = student.averagemark();
i++;
}
}
if (i == 0)
{
std::cout << "No such student has been found!" << std::endl;
}
else if (i >= 2)
{
std::cout << "There're more then 1 student with this surname!" << std::endl;
}
return average;
}
std::string GetAllInfo(const FullName& name) override
{   
int i = 0;
for(const auto& student : group1.sinfo())
{
if (student.sname().surname() == name.surname() && student.sname().name() == name.name())
{
std::cout << "Full Name: " << student.sname().surname() << " " << student.sname().name() << " " << student.sname().patronymic() << 
" marks: " ;
for (auto mark : student.grade())
{
std::cout << mark << "";
}
std::cout << "average mark: " << student.averagemark();
i++;
}
}
if (i == 0)
{
std::cout << "No such student has been found!" << std::endl;
}
return {};
}
std::string GetAllInfo() override
{
for (const auto student : group1.sinfo())
{
std::cout << "Full Name: " << student.sname().surname() << " " << student.sname().name() << " " << student.sname().patronymic() << 
" marks: ";
for (auto mark : student.grade())
{
std::cout << mark << " ";
}
std::cout << "average mark: " << student.averagemark() << std::endl;
}
if (group1.sinfo_size() == 0)
{
std::cout << "There're no students in the group yet" << std::endl;
}
return {};
}

};

double average(const google::protobuf::RepeatedField<int32_t>& grades)
{
double s = 0;
for (const int& i : grades)
{
s += i;
}
return round((s / grades.size())*100)/100;
}

int main()
{
auto name1 = std::make_unique<FullName>();
name1->set_surname("Sergeev");
name1->set_name("Sergey");
name1->set_patronymic("Sergeevich");

auto student1 = std::make_unique<Student>();
student1->set_allocated_sname(name1.release());
student1->add_grade(5);
student1->add_grade(4);
student1->add_grade(4);
student1->set_averagemark(average(student1->grade()));
std::cout << student1->averagemark() << std::endl;


group1.mutable_sinfo()->AddAllocated(student1.release());
for (auto i : group1.sinfo())
{
std::cout << "Full Name: " << i.sname().surname() << " " << i.sname().name() << " " << i.sname().patronymic() << 
" marks: ";
for (auto mark : i.grade())
{
std::cout << mark << " ";
}
std::cout << "average mark: " << i.averagemark() << std::endl;
}
StudentGroup sg1;
sg1.GetAllInfo();
**sg1.GetAverageScore(student1->sname());**
}

下面是proto文件:

syntax="proto3";
message FullName{
string Surname = 1;
string Name = 2;
optional string Patronymic = 3;
}
message Student{
FullName sName = 1;
repeated int32 Grade = 2;
double AverageMark = 3;
}
message StudentsGroup{
repeated Student sInfo = 1;
}

我有几个问题无法解决:

  1. 当我用函数GetAllInfo()或i.a averagemark()计算averagemark时,我得到了一些垃圾,但如果我把它计算为student1->averagemark(),它工作得很好。怎么解呢?
  2. 我不知道如何在函数中输入参数double GetAverageScore(const FullName&重写和std::string GetAllInfo(const FullName&名字)覆盖。我做的似乎都不管用。我得到一个异常:
    inline const ::FullName& Student::_internal_sname() const {
    const ::FullName* p = _impl_.sname_;
    return p != nullptr ? *p : reinterpret_cast<const ::FullName&>(
    ::_FullName_default_instance_);
    

我是编程新手,谢谢你的帮助。谢谢!

student1是一个智能指针,在

student1.release()之后保存nullptr
group1.mutable_sinfo()->AddAllocated(student1.release());

此时student1group1所有。称之为

sg1.GetAverageScore(group1.sinfo(0).sname());
sg1.GetAllInfo(group1.sinfo(0).sname());

最新更新