代码之家  ›  专栏  ›  技术社区  ›  lamas

类实例的C++指针

  •  4
  • lamas  · 技术社区  · 15 年前

    我有一个(C++程序员比我好)简单的类和指针的问题。 我考虑过发布描述我的问题的示例代码,但是我发现用语言来解释它更容易。

    假设我有三个班:

    • A级: 主类-它包含 B C .
    • 乙类: 这个类包含一个输出一些字符串的方法,调用它 Greet() .
    • C类: 这个方法也有一个方法,但该方法必须调用 绿色() 以……为例 在教室里 A . 让我们把它命名 DoSomethingWithB()

    所以程序启动,在我创建的主函数中 . A 再次创建 C . 然后,一个电话 C.DoSomethingWithB(); .

    我的问题开始了:我不能进入 从内部 C .

    显然,我需要给 用b()测量剂量 函数以便我可以调用 B.Greet() 从内部 C

    长话短说: 我该怎么做?

    示例代码输入:

    #include <iostream>
    using namespace std;
    
    class B
    {
    public:
        void Greet( )
        {
            cout<<"Hello Pointer!"<<endl;
        }
    };
    
    class C
    {
    public:
        void DoSomethingWithB( )
        {
            // ... b.Greet( ); Won't work obviously
        }
    };
    
    class A
    {
    public:
     B b; // Not caring about visibility or bad class/variable names here
     C c;
     void StartTest( )
     {
          c.DoSomethingWithB( );
     }
    };
    
    int main( )
    {
        A mainInstance;
        mainInstance.StartTest();
    }
    
    6 回复  |  直到 15 年前
        1
  •  8
  •   Michael Burr    15 年前

    你不会简单地给他传递一个指针或引用吗? B 对象?

    class C 
    { 
    public: 
        void DoSomethingWithB( B& b) 
        { 
            b.Greet( ); // will work fine 
        } 
    }; 
    
    class A 
    { 
    public: 
     B b; // Not caring about visibility or bad class/variable names here 
     C c; 
     void StartTest( ) 
     { 
          c.DoSomethingWithB( b); 
     } 
    };
    

    如果 DoSomethingWithB() 函数不会修改传入的 例如,您应该标记引用 const 所以可以用 康斯特 B对象(例如,如果拥有 A 对象恰好是 常量 ):

    void DoSomethingWithB( B const& b);
    

    对于如何通过 函数的对象:

    • 作为参考( void DoSomethingWithB( B& b) )这将允许函数修改传入的对象。将在传入的对象中重新选择更改。

    • 作为一个 康斯特 参考文献(参考) void DoSomethingWithB( B const& b) )它不会让函数修改传入的对象(除非常量被丢弃-如果对对象执行该操作,则可能导致未定义的行为),否则 康斯特 )

    • 作为指针或 康斯特 指向A的指针 对象(对象) void DoSomethingWithB( B* b) void DoSomethingWithB( B const* pb) )。它们的性能与按引用传递相似,但可以向函数传递一个需要正确处理的空指针(在这种情况下不取消对它的引用)。此外,函数的调用需要稍微更改以传递 对象:

      c.DoSomethingWithB( &b);
      
    • 作为传递值参数( void DoSomethingWithB( B b) )。不同的是,函数可以对传入的对象执行它喜欢的任何操作,并且不会影响最初传递的对象,因为函数处理的是一个副本。缺点是传递参数会导致复制,这可能很昂贵。你也可以通过 康斯特 值,但没有什么可推荐的 康斯特 参考文献。

    注意,当选择参数传递方法时,您应该首先根据您需要函数执行(或不执行)的语义进行选择。以后再担心效率。总是首先设计和代码以确保正确性-只有在设计和代码正确之后才担心效率。

        2
  •  3
  •   Peter Alexander    15 年前

    将功能更改为:

    void DoSomethingWithB(B& b)
    {
        b.Greet();
    }
    

    …在…

    c.DoSomethingWithB(b);
    
        3
  •  2
  •   mwigdahl    15 年前

    您可以按照您所说的那样做--将指向b的指针(或引用)传递到 DoSomethingWithB() :

    class C
    {
    public:
        void DoSomethingWithB(B & bInstance)
        {
            bInstance.Greet( ); // should work fine!
        }
    };
    

    然后像这样调用它:

    class A
    {
    public:
        B b; // Not caring about visibility or bad class/variable names here
        C c;
        void StartTest( )
        {
            c.DoSomethingWithB( b );
        }
    };
    

    我建议在这里使用引用方法,而不是指针,因为:

    1. 您的对象是自动类成员,并且
    2. 在这种情况下,向函数传递一个空的b对象是没有意义的。
        4
  •  0
  •   Zoli    15 年前

    在类C中,声明方法 DoSomethingWithB( 像这样:

    void DoSomethingWithB( B* b )
    {
       b->Greet();
    }
    

    在A班就这样称呼它:

    void StartTest()
    {
        c.DoSomethingWithB( &b );
    }
    

    既然你提到指针,我就用指针来回答。但是在C++中,你应该尝试使用 const 随时提供参考资料。当然,这需要对现有代码做一个小的修改:

    void DoSomethingWithB( const B& b )
    {
       b.Greet();
    }
    
    // and
    
    void StartTest()
    {
        c.DoSomethingWithB( b );
    }
    
        5
  •  0
  •   Jay    15 年前

    我不能从C里面进入B

    为什么不让C向调用者返回信息以便它可以执行操作,而不让C在B中使用C调用方法呢?

    当我点击这些的时候,我发现这是因为我的课程安排得很糟糕。通常,如果我重新考虑他们,困难就会随着一个新的组织而消失。

        6
  •  -1
  •   Alexey Malistov    15 年前
    class C 
    { 
    public: 
        C (B & b) : b(b) {}
        void DoSomethingWithB( ) 
        { 
            // ... b.Greet( ); Use b;
        } 
    private:
        B & b;
    }; 
    
    class A 
    { 
    public: 
     B b; // Declare b before c! 
     C c; 
     A() : c (b) {}
     void StartTest( ) 
     { 
          c.DoSomethingWithB( ); 
     } 
    };