__JAN__ 2022-01-25 10:44 采纳率: 100%
浏览 38
已结题

C++ has-a 关系的建立(私有继承)中遇到了问题

#include <iostream>
#include <valarray>
using namespace std;
//C++继承模板类的原代码

class Student :private string, private valarray<double>
{
public:
    string name;
    //注意这里只是模板类声明,并不是具体实现,因此没有开辟空间
    valarray <double> score;
public:
    //构造函数这里我们其实可以有很多的选择,下面写出一些,这里选择列表初始化
    //默认的构造函数,没有名字,没有成绩
    Student(): string("no name"), valarray<double>() {
        cout << "默认构造函数的调用" << endl;
    }

    //可以初始化名字和成绩的数量
    Student(const string & s, int n) : string(s), valarray<double>(n) {
        cout << "(const string & s, int n)的调用" << endl;
    }

    //初始化成绩的数量
    explicit Student(int n) : string("na name"), valarray<double>(n) {
        cout << "Student(int n)的调用" << endl;
    }

    //既然可以用string &来构造string初始化string,那当然可以用 valarray<double> & 来初始化 valarray <double>
    //与string 一样,列表初始化调用其构造函数
    Student(const string & s, valarray<double> & v) : string(s), valarray<double>(v) {
        cout << "(const string & s, valarray<double> & v)的调用" << endl;
    }

    //可以提供一个C的接口,让类的健壮性更强
    //让所有成绩全初始化为val
    Student(const char * s, double * val, int n) : string(s), valarray<double>(val,n) {
        cout << "(const char * s, double * val, int n)的调用" << endl;
    }

    //因为在类中没有用到new操作,所以写一个空实现的析构函数即可
    ~Student() = default;

    //类方法,我们用的私有继承,所以string类中的类方法和valarray中的类方法全部变为私有,但我们可以在派生类中提供对外的接口
    //假设写一个求平均分的类方法,虽然不能Student::string::length(),但我们可以这样做
    double average() const; //在类中实现的函数会自动转换为内联函数,这里在类外写

    //友元函数虫重载 <<
    friend ostream & operator<<(ostream & os,const Student & s);
};


ostream & operator<<(ostream & os,const Student & s)
{
    os << "name is : " << s.name << endl;
    os << "score is : " << endl;
    for(int i=0;s.score.size();i++){
        cout << s.score[i] << " ";
    }
    return os;
}
//使用类方法
double Student::average() const
{
    //return score.sum() / score.size();
    return valarray<double>::sum() / (double)valarray<double>::size();
}
int main()
{
    typedef Student S;
    //下面用各种构造函数来进行对象的初始化
    //默认构造函数
    S s1;
    S s2 = S{"lilei", 3};
    S s3 {3};
    valarray<double> v(3);
    S s4 {"liha", v};
    double sor = 80.4;
    S s5 = {"hello", &sor, 3};
    cout << s5.average();
}

https://img-blog.csdnimg.cn/b1569c6bff7446b095b061202c378511.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASkFONjA1NQ==,size_20,color_FFFFFF,t_70,g_se,x_16
 这样看是没错

但在有这样的警告

https://img-blog.csdnimg.cn/59715f22729b416387c09abe70c11b61.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASkFONjA1NQ==,size_14,color_FFFFFF,t_70,g_se,x_16

 显示我们定义的构造函数没有使用,average显示出来的也不对,不知道大佬们有没有什么解决问题的办法,帮帮孩子把(快哭了)
  • 写回答

6条回答 默认 最新

  • 爱晚乏客游 2022-01-25 11:17
    关注

    img


    你的score在哪里赋值?

    //test.h
    #pragma once
    #include "stdafx.h" //非vs2015可以去掉这个头文件
    #include <iostream>
    #include <valarray>
    
    using namespace std;
    //C++继承模板类的原代码
    
    class Student :private string, private valarray<double>
    {
    public:
        string name;
        //注意这里只是模板类声明,并不是具体实现,因此没有开辟空间
        valarray <double> score;
    public:
        //构造函数这里我们其实可以有很多的选择,下面写出一些,这里选择列表初始化
        //默认的构造函数,没有名字,没有成绩
        Student() : string("no name"), valarray<double>() {
            cout << "默认构造函数的调用" << endl;
        }
    
        //可以初始化名字和成绩的数量
        Student(const string & s, int n) : string(s), valarray<double>(n) {
            cout << "(const string & s, int n)的调用" << endl;
        }
    
        //初始化成绩的数量
        explicit Student(int n) : string("na name"), valarray<double>(n) {
            cout << "Student(int n)的调用" << endl;
        }
    
        //既然可以用string &来构造string初始化string,那当然可以用 valarray<double> & 来初始化 valarray <double>
        //与string 一样,列表初始化调用其构造函数
        Student(const string & s, valarray<double> & v) : string(s), valarray<double>(v) {
            cout << "(const string & s, valarray<double> & v)的调用" << endl;
        }
    
        //可以提供一个C的接口,让类的健壮性更强
        //让所有成绩全初始化为val
        Student(const char * s, double * val, int n) : string(s), valarray<double>(val, n) {
            cout << "(const char * s, double * val, int n)的调用" << endl;
        }
    
        //因为在类中没有用到new操作,所以写一个空实现的析构函数即可
        ~Student() = default;
    
        //类方法,我们用的私有继承,所以string类中的类方法和valarray中的类方法全部变为私有,但我们可以在派生类中提供对外的接口
        //假设写一个求平均分的类方法,虽然不能Student::string::length(),但我们可以这样做
        double average() const; //在类中实现的函数会自动转换为内联函数,这里在类外写
    
                                //友元函数虫重载 <<
        friend ostream & operator<<(ostream & os, const Student & s);
    };
    
    
    ostream & operator<<(ostream & os, const Student & s)
    {
        os << "name is : " << s.name.c_str() << endl;
        os << "score is : " << endl;
        for (int i = 0; s.score.size(); i++) {
            cout << s.score[i] << " ";
        }
        return os;
    }
    //使用类方法
    double Student::average() const
    {
        //return score.sum() / score.size();
        double a = valarray<double>::sum();
        double b = (double)valarray<double>::size();
        return valarray<double>::sum() / (double)valarray<double>::size();
    }
    
    //main.cpp
    #include "stdafx.h"
    #include"test.h"
    #include <iostream>
    using namespace std;
    
    int main()
    {
        typedef Student S;
        //下面用各种构造函数来进行对象的初始化
        //默认构造函数
        S s1;
        S s2 = S{ "lilei", 3 };
        S s3{ 3 };
        valarray<double> v(3);
        S s4{ "liha", v };
        double sor = 80.4;
        S s5 = { "hello", &sor, 3 };
        cout << s5.average();
        system("pause");
        return 0;
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 2月2日
  • 已采纳回答 1月25日
  • 创建了问题 1月25日

悬赏问题

  • ¥15 蓝桥oj3931,请问我错在哪里
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染