gpt4 book ai didi

c++ - 如何在另一个类(class)中使用类(class)成员的正确方法?

转载 作者:行者123 更新时间:2023-11-28 04:33:52 25 4
gpt4 key购买 nike

我正在尝试使用来自不同类的类成员,将“class uart”添加到“class parser : public uart

但是我不能在解析器类中使用成员变量,例如(bufer_size、buffer 或 state Enum,值不会改变或更新)我可以使用这些变量的唯一方法是将它们用作外部变量,但我会喜欢以类(class)成员的方式去做。

下面请找到我的代码:

主要内容:

#include <stdio.h>
#include "parser.h"
int main()
{
parser m_parser;
m_parser.test();
return 0;
}

uart.h

#include <stdint.h>
#include <stdio.h>

//extern uint16_t buffer_size;
//extern char buffer[1024];

class uart
{
public:
// Construction
uart();

//..... some functions
void Initialize();

//members
enum STATE_enum
{
Buffering_message=0,
Message_received,
Buffering_empty
};
STATE_enum state;

uint16_t buffer_size;
char buffer[1024];
protected:
// static void UARTHandler(app_uart_evt_t * p_event);
void Message();
// Singleton instance
static uart * m_instance;
};

uart.cpp

#include "uart.h"
//uint16_t buffer_size=0;
//char buffer[1024];

uart * uart::m_instance = 0; // Singleton instance

uart::uart()// Construction
{
state = Buffering_empty;
m_instance = this;
}

void uart::Initialize()
{
}
/*void UART::UARTHandler(app_uart_evt_t * p_event)
{
Message();
}*/
void uart::Message()
{
uint8_t value;
// while ((app_uart_get(&value)) == NRF_SUCCESS) //specific function from my microcontroller stack for reading RX bytes
{
if(value == 0x0A ) // message end /r
state = Message_received;
}
switch (state)
{
case Message_received:
printf("message:[%s] buffer_size:[%d]", buffer,buffer_size); //printf fine from there
break;
case Buffering_message:
buffer[buffer_size++] = value;
break;
default:
break;
}
}

解析器.h

#include <stdio.h>
#include <stdint.h>
#include "uart.h"

class parser : public uart
{
public:
parser();

void test();
static parser * m_instance;

static inline parser & Instance()// Singleton access
{
return *m_instance;
}
};

解析器.cpp

#include "parser.h"

class parser * parser::m_instance = 0;

// Constructor
parser::parser()
{
m_instance = this;
}

void parser::test()
{
printf("state %s", state); // sending AT command

// memset(buffer, 0, buffer_size);
// buffer_size = 0;
}

我应该将上面的用作公共(public)类还是将其添加为友元类,或者只是用作外部变量?

最佳答案

最初的问题显然是使用了错误的格式说明符:

void parser::test()
{
printf("state %s", state);
// ^^
}

%s 仅适用于 C 字符串(即以 null 结尾的 char 数组)。在这里,state 被解释为一个指针,但它指向无效地址(未定义的行为),因此您的应用程序可能在它能够产生任何输出之前就崩溃了。

即使 state did 包含有效地址,您仍然会遇到未定义的行为,因为 %s 需要 类型的参数>char*(为了避免UB,需要强制转换)。

使用正确的格式说明符来解决问题:

printf("state %u", static_cast<unsigned int>(state));

您仍然需要转换以避免 UB,因为 %u 需要 unsigned int,但您的枚举不是(或者您可以使用 %d 并转换为 int)。

显然,您现在也尝试(因为没有发现真正的错误)通过使用单例来绕过您假设它是什么——不幸的是,由于错误地实现了模式,您你的设计有缺陷。

如何修复?首先,放弃单例。在给定的情况下绝对没有必要。然后三思(下面的问题之前):解析器真的是一个 UART 吗?不考虑代码,而是考虑概念,我明确地说“不”。所以你也不应该让 inherit parser 来自 uart。而是让它聚合一个:

class parser // : public uart
{
uart m_uart;
public:
// ...
void test()
{
printf("%u", static_cast<unsigned int>(m_uart.state);
}

};

或者,您可以通过指针或引用(对构造函数)在外部提供它并按原样存储它,但随后您也会很快遇到生命周期管理,我建议您返回更高级的概念有了更多的经验......

不过,您应该习惯的是:封装。不要公开成员变量,除非您真的希望它们在任何地方 都可以更改。例如,buffer 是私有(private)(甚至未 protected )的热门候选对象。

最后是buffer_size:如果您打算用它来计算缓冲区中当前 值的数量,那么它很好。如果它表示可以 存储的最大数据数,那么它就是冗余的。在任何需要它的地方,您都可以通过 sizeof(buffer)/sizeof(*buffer) 获取大小(除非数组已衰减为指针!)。按第一个元素的大小划分是必要的,因为 sizeof 始终以字节为单位提供大小,而不是以元素数量为单位。

元素数量的大小是您通过 std::array::size 获得的;你应该更喜欢std::array由于出色的界面,优于原始数组!也许std::vector even 是更好的选择吗?

关于c++ - 如何在另一个类(class)中使用类(class)成员的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52081958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com