class Class1 //Would be object mClass1
{
public:
void Function1()
{
a ;
}
private:
int a = 0;
Class2 mClass2;
}
(在此處的空白處進行編輯以澄清 Class2 未在 Class1 之后定義;它們位于單獨的檔案中。)
class Class2 //Would be object mClass2
{
public:
Function2()
{
Function1(); // Would be from mClass1
}
}
所以 Class1 創建了一個 Class2 物件的實體,并且 Class2 物件有一個成員函式,它想要訪問“父”物件的成員函式,而不使用繼承。
我不知道我特別需要搜索什么來了解這一點。它與取消參考new指標有關嗎?建構式型別/初始化?它有術語嗎?“嵌套類”調出在另一個類中定義的類,這不是這個類。
uj5u.com熱心網友回復:
沒有繼承就無法獲得“父類”。因此,您應該將函式作為引數傳遞,如果您多次使用它,也許可以在類 2 的建構式中傳遞它。參見例如:https : //www.cprogramming.com/tutorial/function-pointers.html
uj5u.com熱心網友回復:
你不可以做這個。Class2定義時還不知道Class1,因此Class1::mClass2不可能創建資料成員。但是這個問題可以通過定義Class2beforeClass1并Class2::Function2()在類外僅在之后實作來解決Class1。
至于在Function1()里面呼叫Function2(),Class2需要知道呼叫的物件Function1()。您可以使用在建構式中初始化的參考成員:
// Forward-declaration of Class1 so that Class2 will be able to define
// references or pointers to Class1.
class Class1;
class Class2
{
public:
// Constructor that requires a reference to our parent object.
explicit Class2(Class1& parent)
: parent_(parent)
{ }
// Just declare the function. We need to implement it later, outside
// this class definition because Class1 is not fully known yet and as
// a result we can't have calls to Function1() because the compiler
// doesn't know that function yet.
void Function2();
private:
// This is just a reference, so it works even if Class1 is not fully
// known yet.
Class1& parent_;
};
class Class1
{
public:
void Function1() { /* ... */ }
private:
int a = 0;
Class2 mClass2{*this}; // Pass ourself as the parent object.
};
// Class1 is fully known now, so we can do calls to Function1().
inline void Class2::Function2()
{
parent_.Function1();
}
這會起作用,但它有一個重要的含義:它禁用了 的賦值運算子Class2。在這種情況下,這可能是您想要的,因為 的兩個副本Class2可能不應該具有相同的Class1父物件。
但是,我不明白您為什么需要這樣做。它無緣無故地使事情復雜化。為什么不簡單地傳遞應該用作函式引數的Class1物件Function2()呢?所以:
class Class1;
class Class2
{
public:
void Function2(Class1& c1_obj);
};
class Class1
{
public:
void Function1() { /* ... */ }
private:
int a = 0;
Class2 mClass2;
};
inline void Class2::Function2(Class1& c1_obj)
{
c1_obj.Function1();
}
所以每當Class1需要呼叫時Class2::Function2(),只需傳遞*this給它。它更簡單,并且沒有持有指向另一個物件的參考或指標的缺點。
uj5u.com熱心網友回復:
使用規范類 - 無法做到這一點,因為Class2內部不完整Class1,如果您宣告Class2內部Class1(作為嵌套類),它將無法訪問Class1,因為Class1不完整!
看起來像一個無法解決的悖論?它在 OOP 領域無法解決,但可以像 Nikos 展示的那樣躲避。但是在某些情況下未定義型別的問題可以在 C 或類似的面向概念的語言中通過使用 CRTP- Curiously recurring template 來解決。
在您的用例中是否可能,以及它的復雜程度取決于您追求的目的。這是一個矛盾的 CRTP 行為的例子 - 基類的成員能夠呼叫派生類的成員:
#include <iostream>
template < class T>
class Base {
public:
template <class U>
struct Accessor : public U {
static void evoke_foo( T& obj)
{
return (obj.*(static_cast< void(T::*)() >(&Accessor::foo))) ();
}
};
void evoke( )
{
Accessor<T>::evoke_foo( *static_cast<T*>(this) );
}
};
class Derived : public Base<Derived> {
protected:
void foo() { std::cout << "Foo is called" << std::endl; }
};
int main()
{
Derived a;
a.evoke(); // evoke belongs to base.
}
現在如果我們想foo()在這里自動確定回傳型別,這將成為一段非常復雜的代碼。在標準同名evoke方法的實作中解決了一些類似的問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/346227.html
