C++ C++;通过函数初始化类指针
我有一个程序,它有一个类C++ C++;通过函数初始化类指针,c++,class,pointers,C++,Class,Pointers,我有一个程序,它有一个类class a的单个实例和多个类class B的实例,其中class B的每个实例都有一个指向class a的单个实例的指针。我想我可以在main()中启动它们,然后将class A的单个实例的地址传递给class B的所有实例。我想知道这是否正确,我一直在研究继承,但根据我的理解(这通常是错误的),如果您继承另一个类,那么该类每次都会被初始化,因此创建了多对多关系,而我想要一对多关系。我附上了一些代码。如有任何建议,将不胜感激 // C/C++ standard lib
class a
的单个实例和多个类class B
的实例,其中class B
的每个实例都有一个指向class a
的单个实例的指针。我想我可以在main()
中启动它们,然后将class A
的单个实例的地址传递给class B
的所有实例。我想知道这是否正确,我一直在研究继承,但根据我的理解(这通常是错误的),如果您继承另一个类,那么该类每次都会被初始化,因此创建了多对多关系,而我想要一对多关系。我附上了一些代码。如有任何建议,将不胜感激
// C/C++ standard library
#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;
class A {
public:
double get_value(void) {
return value;
}
private:
double value;
};
// Forward declare A if split over files
class B {
public:
void assign_pointer(A class_a_to_assign) {
class_a = &class_a_to_assign; // assign the pointer the address to point to
}
void update_my_value(void) {
value_b += class_a->get_value();
}
double get_value(void) {
return value_b;
}
private:
double value_b = 0.1;
A* class_a; // pointer to class A
};
int main() {
cout << "hello world" << endl;
// create 2 instances of B there could be thousands of these tho.
B b1;
B b2;
// create 1 instance of A
A a1;
// Now I want both instances of the B class to point to the one instance of A
b1.assign_pointer(a1);
b2.assign_pointer(a1);
// THen do stuff with B so that if any changes occur in A, then they can be automatically updated in class B through the pointer
b1.update_my_value();
b2.update_my_value();
cout << b1.get_value() << " and " << b2.get_value() << endl;
return 0;
}
//C/C++标准库
#包括
#包括
#包括
使用名称空间std;
甲级{
公众:
双get_值(void){
返回值;
}
私人:
双重价值;
};
//如果在文件上拆分,则向前声明
B类{
公众:
void assign_指针(类_A_to_assign){
class_a=&class_a_to_assign;//将要指向的地址分配给指针
}
无效更新我的值(无效){
值_b+=类_a->获取值();
}
双get_值(void){
返回值_b;
}
私人:
双值_b=0.1;
A*class_A;//指向类A的指针
};
int main(){
cout下面的函数违反了您仅创建一个A
实例并使用指向该A
实例的指针的意图
void assign_pointer(A class_a_to_assign) {
class_a = &class_a_to_assign; // assign the pointer the address to point to
}
由于您接受的是按值分配的类,因此存在两个问题:
每次调用函数时,都会创建一个新的a
实例
您正在存储指向临时对象的指针。一旦函数返回,指针将变为无效指针
通过将参数设置为引用类型,可以解决这两个问题
void assign_pointer(A& class_a_to_assign) {
class_a = &class_a_to_assign; // assign the pointer the address to point to
}
此外,正如在注释中提到的,最好在B
对象之前创建A
对象,因为您希望A
比B
对象更长寿
int main() {
cout << "hello world" << endl;
// create 1 instance of A
A a1;
// create 2 instances of B there could be thousands of these tho.
B b1;
B b2;
...
}
intmain(){
cout您所描述的内容听起来很像。处理这种情况的一种方法是让singleton类包含一个静态
方法,该方法返回类的单个实例。因此它看起来像这样:
class A {
public:
A() { /* constructor */ }
~A() { /* destructor */ }
static A* getInstance();
double get_value(void) {
return value;
}
private:
double value;
};
static A gSharedInstance;
static A* A::getInstance()
{
return &gSharedInstance;
}
static
方法将位于实现(.cpp)文件中,如下所示:
class A {
public:
A() { /* constructor */ }
~A() { /* destructor */ }
static A* getInstance();
double get_value(void) {
return value;
}
private:
double value;
};
static A gSharedInstance;
static A* A::getInstance()
{
return &gSharedInstance;
}
这将在静态初始化时构造一个A
,当调用上述方法时,它将返回指向该静态共享实例的指针。现在,无论您想在何处使用A
,您只需执行以下操作:
A* sharedA = A::getInstance();
double value = sharedA->getValue(); // Or whatever you need from it.
请注意,singleton本质上是一个全局变量,全局变量有一些问题(例如,在本例中,它的值成员集在哪里?),但如果类表示某种真正唯一的资源(例如,设备上唯一的麦克风),则,那么就值得使用一个单例来表示它。在这种情况下,最好将其设置为只读,这样就不能在许多不同的地方设置其状态。另外,请注意,您可能需要添加代码来处理同时访问它的多个线程。首先,您的代码中存在一个严重问题:
void assign_pointer(A class_a_to_assign) {
class_a = &class_a_to_assign; // assign the pointer the address to point to
}
这里,class\u a\u to\u assign
是一个按值函数参数,它在生存期方面与任何函数局部变量大致相同。换句话说,一旦控件离开方法的作用域,class\u a
就成为一个悬空指针(指向不再存在的局部对象的指针)。快速修复程序简单明了:
void assign_pointer(A &class_a_to_assign) {
class_a = &class_a_to_assign; // assign the pointer the address to point to
}
区别只是一个字符——函数参数声明中的符号将其从临时值转换为对更长寿命对象的引用
接下来,如果您有一个类a
的单个对象,您是否考虑过将其设置为单例对象?这样,B
的实例甚至不需要保留该指针,a
本身管理该实例。关于设计单例类,有很多说法,一个粗糙而幼稚的实现类似于:
class A {
A(); // note it's private
public:
int getValue() const;
static A &instance() {
static A retVal;
return A;
};
};
class B {
public:
void update_my_value(void) {
value_b += A::instance().get_value();
}
};
int main() {
A::instance(); // to warmup the static instance before any users are created
B b1; // no assign_pointer is needed as A is a Singleton
B b2; // and every B always knows where to find it
}
一个改进是在所有B
对象之前创建a1
,以确保它比它们更长寿,因为它们依赖于它。继承不是多对多的,它只是每个对象的一对一关系。(另外,a
的转发声明不足以满足B
的定义,您的示例读取未初始化的a::value
)这里没有其他(明显)错误(即使可以进行重大改进)--这就是你的全部问题吗?另一个问题:确保B
只能通过在构造函数中执行explicit B(A*A):class_A(A){
来从A*
实例化。