请教一个跨命名空间 C++拷贝构造函数的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hackpro
V2EX    C

请教一个跨命名空间 C++拷贝构造函数的问题

  •  1
     
  •   hackpro 2017-05-22 17:27:24 +08:00 2418 次点击
    这是一个创建于 3123 天前的主题,其中的信息可能已经有所发展或是发生改变。

    中午吃饭组里一个同事问的,折腾的一下午还是没搞定,牛皮吹大了,请教下大家如何解决,谢谢各位

    基本需求是两个命名空间存在相同的一个类,TA/TB 以示区别

    怎么将命令空间 A 中类 TA 的对象作为命名空间 B 中类 TB 构造函数的参数传入并访问其中的字段?

    #include "stdafx.h" #include <iostream> using namespace std; class B::TB; namespace A { class TA { privat: char *m_pstr; public: TA(const char *cstr) { if (cstr == nullptr) { m_pstr = nullptr; } else { int len = strlen(cstr); m_pstr = new (nothrow)char[len+1]; memcpy(m_pstr, cstr, len); m_pstr[len] = '\0'; } } friend class B::TB; }; } namespace B { class TB { private: char *m_pstr; public: TB(const char *cstr) { if (cstr == nullptr) { m_pstr = nullptr; } else { int len = strlen(cstr); m_pstr = new (nothrow)char[len+1]; memcpy(m_pstr, cstr, len); m_pstr[len] = '\0'; } } //friend class A::TA; TB(const A::TA& ta) { this->m_pstr = ta.m_pstr; } ~TB() { if (m_pstr != nullptr) { delete []m_pstr; m_pstr = nullptr; } } }; } int main(int argc, char* argv[]) { A::TA a("This is A"); B::TB b = a; return 0; } 
    12 条回复    2017-05-23 14:48:14 +08:00
    Damenly0
        1
    Damenly0  
       2017-05-22 17:46:50 +08:00
    using namespace std;
    namespace B{
    class TB;
    }

    namespace A
    {
    xss
        2
    xss  
       2017-05-22 17:57:15 +08:00
    用泛型不可以么,? 这样还可以解耦.....
    ```
    template <class TA> class TB {
    TB(TA& that){
    this.value = that.value;
    }
    }
    ```
    luoqeng
        4
    luoqeng  
       2017-05-22 18:07:45 +08:00
    TB(const A::TA& ta) {
    // this->m_pstr = ta.m_pstr;

    if (ta.m_pstr != NULL) {
    int len = strlen(ta.m_pstr);
    m_pstr = new (nothrow)char[len+1];
    memcpy(m_pstr, ta.m_pstr, len);
    m_pstr[len] = '\0';
    }
    }

    深拷贝就行了啊
    hackpro
        5
    hackpro  
    OP
       2017-05-22 18:49:26 +08:00
    @Damenly0 #1 感谢大神,问题出在声明特定命名空间中函数

    @xss #2 泛型可以解耦啥意思,可以说具体些吗?

    @sfqtsh # 3 感谢提供,清楚地说明白了为啥命名空间中的函数不能直接前置声明

    @luoqeng #4 这个是实例代码,这样做的目的就是为了避免深层拷贝
    RitchieLee
        6
    RitchieLee  
       2017-05-22 18:49:29 +08:00
    @sfqtsh 亲测大佬的方法可解决楼主的问题
    hackpro
        7
    hackpro  
    OP
       2017-05-22 19:11:16 +08:00
    @Damenly0 #1
    @xss #2
    @sfqtsh #3
    @luoqeng #4

    请教各位,如果想将权限收紧,只将命名空间中某个类的函数作为友元,即 B::TB::TB(),上面这段怎么继续改?
    我尝试了下,没有成功……

    namespace A{class TA;}
    namespace B{
    class TB{
    TB(const A::TA& ta);
    };
    }

    namespace A
    {
    class TA
    {
    friend B::TB::TB(const TA& ta);
    };
    }
    Damenly0
        8
    Damenly0  
       2017-05-22 19:37:53 +08:00
    因为 B::TB::TB()已经涉及到具体 B 的实现,而非声明,考虑到 TB 又依赖于 TA 的实现。如#2 所说,可用 template 解耦
    http://stackoverflow.com/questions/10546391/specify-a-class-member-function-as-a-friend-of-another-class
    wevsty
        9
    wevsty  
       2017-05-22 20:25:43 +08:00
    为什么不用继承?
    xss
        10
    xss  
       2017-05-23 09:51:39 +08:00
    或许我写的 template 误导你了. 那个 class TA 实际上应该是 class T.

    实际上按照你的需求, TB 是对 TA 是有一定要求的.
    一般按照这个尿性发展下去, 你的 TB 一定会对 TA 的要求越来越多. 而一旦 TA 有什么风吹草动, 你就得改一大堆东西.


    直接给例子吧:

    xss@xss [09:47:01] : ~/Code
    $ g++ -c test.cpp -o xxxeee
    xss@xss [09:47:09] : ~/Code
    $ cat test.cpp
    template <class T>
    class TB{
    public:
    TB(T& that){
    this.value = that.value;
    }
    friend void T::foo(void);
    private:
    int value;
    };

    我上面并没有生命一个 TA, 直接用 T 代替, 但是实际上也是可以编译通过的.
    这样的话, 你至少不用考虑 TA 的问题, 因为 T 可以是任何东西.....
    hackpro
        11
    hackpro  
    OP
       2017-05-23 14:29:53 +08:00
    @xss 感谢回复 不过大兄弟你这段代码没考虑 namespace 问题啊
    另外代码编译没有问题 但是没有实质的调用 编译器并不会将这段代码实例化……
    xss
        12
    xss  
       2017-05-23 14:48:14 +08:00
    @hackpro 我只是再跟你说解耦的问题.

    namespace 也不影响应该,
    TB<othernamespace::TA>(objTA)

    这个完全是你在实例化这个模板类的时候需要考虑的问题.
    你只需要对 class TB 有个合理的设计就行了.
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4615 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 09:45 PVG 17:45 LAX 01:45 JFK 04:45
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86