• 发现《深入理解C++11》中扩展的friend代码的错误


    目前在总结现代C++的新特性,看了《深入理解C++11》这本书。
    今天看到扩展的friend语法这一节,遇到了问题。本节电子版内容参见:https://book.2cto.com/201306/25354.html

    未改良前的代码如代码清单2-21所示(在Linux下按照下面的编译指令能够通过),接着作者总结出了这种方法4点不好,给出了改良版代码(如代码清单2-22所示)。我要吐槽的是,反复试了好久,这改良版根本就不能够通过编译,感觉代码写的相当的鬼畜。

    代码清单2-21
     
    #include<iostream>
    using namespace std;
     
    // 为了方便测试,进行了危险的定义
    #ifdef UNIT_TEST
    #define private public
    #endif
    class Defender {
    public:
        void Defence(int x, int y){}
        void Tackle(int x, int y){}
     
    private:
        int pos_x = 15;
        int pos_y = 0;
        int speed = 2;
        int stamina = 120;
    };
     
    class Attacker {
    public:
        void Move(int x, int y){}
        void SpeedUp(float ratio){}
     
    private:
        int pos_x = 0;
        int pos_y = -30;
        int speed = 3;
        int stamina = 100;
    };
     
    #ifdef UNIT_TEST
    class Validator {
    public:
        void Validate(int x, int y, Defender & d){}
        void Validate(int x, int y, Attacker & a){}
    };
     
    int main() {
        Defender d;
        Attacker a;
        a.Move(15, 30);
        d.Defence(15, 30);
        a.SpeedUp(1.5f);
        d.Defence(15, 30);
        Validator v;
        v.Validate(7, 0, d);
        v.Validate(1, -10, a);
        return 0;
    }
    #endif
    // 编译选项:g++ 2-9-3.cpp -std=c++11 -DUNIT_TEST                 
    
    代码清单2-22
     
     #include<iostream>
     using namespace std;
     
    template <typename T> class DefenderT {
    public:
        friend T;
        void Defence(int x, int y){}
        void Tackle(int x, int y){}
     
    private:
        int pos_x = 15;
        int pos_y = 0;
        int speed = 2;
        int stamina = 120;
    };
     
    template <typename T> class AttackerT {
    public:
        friend T;
        void Move(int x, int y){}
        void SpeedUp(float ratio){}
     
    private:
        int pos_x = 0;
        int pos_y = -30;
        int speed = 3;
        int stamina = 100;
    };
     
    using Defender = DefenderT<int>;   // 普通的类定义,使用int做参数
    using Attacker = AttackerT<int>;
     
    #ifdef UNIT_TEST
    class Validator {
    public:
        void Validate(int x, int y, DefenderTest & d){} 
        // 该行和下一行均报错:语法错误
        void Validate(int x, int y, AttackerTest & a){} 
        //我在想这里的AttackerTest 是下面两行定义的,尝试把下面的两行提到前面错误变得更多了
    };
     
    using DefenderTest = DefenderT<Validator>;  // 测试专用的定义,Validator类成为友元
    using AttackerTest = AttackerT<Validator>;
     
    int main() {
        DefenderTest d;
        AttackerTest a;
        a.Move(15, 30);
        d.Defence(15, 30);
        a.SpeedUp(1.5f);
        d.Defence(15, 30);
        Validator v;
        v.Validate(7, 0, d) ;   
        //此处和下一行均报错:函数不接受3个参数
        v.Validate(1, -10, a);
        return 0;
    }
    #endif
    // 编译选项:g++ 2-9-4.cpp -std=c++11 -DUNIT_TEST
    

    最后修改方法

    using DefenderTest = DefenderT<Validator>;  // 测试专用的定义,Validator类成为友元
    using AttackerTest = AttackerT<Validator>;
    把这两行提到
    class Validator  之前,因为他的成员函数用到了这些定义
    又因为 using DefenderTest = DefenderT<Validator>; 用到了 Valkidator 所以 要在这句话之前,前置声明一下 class Validator;
    

    感谢hdt的帮助,问题帖来源点击此处

    新战场:https://blog.csdn.net/Stephen___Qin
  • 相关阅读:
    0Day – 2011.01.26
    JQuery_PHP 开始新的旅途
    0Day – 2011.01.25
    0Day – 2011.02.04
    Delphi 必须的一致.
    0Day – 2011.01.28
    0Day – 2011.02.23[From B4A]
    足球 看球悲惨的回忆.
    Delphi – EurekaLog6.1.01Ent下载地址
    ubuntu 拨号
  • 原文地址:https://www.cnblogs.com/Stephen-Qin/p/9120805.html
Copyright © 2020-2023  润新知