Mandelbrot_Set 发表于 2015-10-26 11:07:10

[NUCLEO-L476RG开发] 先写段CPP玩玩,重载<<运算符

看上去工作的挺好!:)
OStream & operator<<(OStream& stream,char c)
{
      stream.Putc(c);
      return stream;
}
//;OStream 基类名.

O0 下编译
; operator<<(OStream &, char)
EXPORT _ZlsR7OStreamc
_ZlsR7OStreamc
PUSH            {R4-R6,LR}
MOV             R4, R0
MOV             R5, R1
LDR             R0,
MOV             R1, R5
LDR             R2,
MOV             R0, R4
BLX             R2
MOV             R0, R4
POP             {R4-R6,PC}
O3 下编译
; operator<<(OStream &, char)
EXPORT _ZlsR7OStreamc
_ZlsR7OStreamc
PUSH            {R4,LR}
MOV             R4, R0
LDR             R0,
LDR             R2,
MOV             R0, R4
BLX             R2
MOV             R0, R4
POP             {R4,PC}
=====================================

LDR             R2,
BLX             R2
是获取成员函数地址(这具体与调用那个函数有关),并跳转。
R0,R1什么传个参数就不讲了
可以看出优化明显把
MOV             R5, R1;MOV             R1, R5;
给优化了。

另外,如预计的那样:main在返回之前调用了析构函数
。。。。
BL            _ZlsR7OStreamPc ; operator<<(OStream &,char *)
ADD             R0, SP, #0x170+var_90
BL            _ZN11UartOStreamD2Ev ; UartOStream::~UartOStream()
MOVS            R0, #1
ADD             SP, SP, #0x154
POP.W         {R4-R9,PC}
; End of function main

感觉好水。。。:L

代码:

myio.cpp:

#include "myio.hpp"
OStream & operator<<(OStream& stream,char c)
{
      stream.Putc(c);
      return stream;
}

OStream & operator<<(OStream& stream,char* s)
{
      stream.Puts(s);
      return stream;
}


UartOStream uartout;

LedOStream   led;
myio.hpp
#ifndef _MY_IO_HPP
#define _MY_IO_HPP
#include "stm32l4xx_hal.h"

class OStream
{
public:
      OStream()
      {
      }
      virtual void Putc(char c) = 0;
      virtual void Puts(char* s) = 0;
};

class UartOStream: public OStream
{
private:
      UART_HandleTypeDef UARTHandle;
public:
      UartOStream()
      {
          UARTHandle.Instance = USART2;
                UARTHandle.Init.BaudRate = 9600;
                UARTHandle.Init.WordLength = UART_WORDLENGTH_8B;
                UARTHandle.Init.StopBits = UART_STOPBITS_1;
                UARTHandle.Init.Parity = UART_PARITY_NONE;
                UARTHandle.Init.HwFlowCtl= UART_HWCONTROL_NONE;
                UARTHandle.Init.Mode = UART_MODE_TX_RX;
                UARTHandle.Init.OverSampling = UART_OVERSAMPLING_16;
                UARTHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
               
                GPIO_InitTypeDefGPIO_InitStruct;
    /* Enable UART2 GPIO TX/RX clock */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /* Enable USART2 clock */
    __HAL_RCC_USART2_CLK_ENABLE();   
    /* Configure USART2 Rx and Tx as alternate function*/
    GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; // GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
   
    /* Enable and set USART2 Interrupt to the highest priority */
    HAL_NVIC_SetPriority(USART2_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
               
                if(HAL_UART_Init(&UARTHandle) != HAL_OK)
                {
                        //throw;
                        while(1);
                }
      }
      virtual void Putc(char c)
      {
                HAL_UART_Transmit(&UARTHandle, (uint8_t *)&c, 1, 0xFFFF);
      }
      virtual void Puts(char *s)
      {
                while(*s)
                {
                        Putc(*(s++));
                }
      }
      ~UartOStream()
      {
                char ADDR;
                sprintf(ADDR,"0x%08x\n",this);
                Puts("I AM BEING KILLED , I AM AT ");
                Puts(ADDR);
      }
};

class LedOStream :public OStream
{
private:
      int m_Interval;
public:
      void SetInterval(int n){m_Interval = n;}
      ~LedOStream()
      {
                HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
      }
      LedOStream()
      {
          m_Interval = 0;
               
                GPIO_InitTypeDefgpioinitstruct;
                __HAL_RCC_GPIOA_CLK_ENABLE();
                /* Configure the GPIO_LED pin */
                gpioinitstruct.Pin   = GPIO_PIN_5;
                gpioinitstruct.Mode= GPIO_MODE_OUTPUT_PP;
                gpioinitstruct.Pull= GPIO_NOPULL;
                gpioinitstruct.Speed = GPIO_SPEED_FREQ_HIGH;
                HAL_GPIO_Init(GPIOA, &gpioinitstruct);
                HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
      }
      virtual void Putc(char c)
      {
                        if(c=='1')
                              HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
                        else if(c=='0')
                              HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
                              
      }
      virtual void Puts(char *s)
      {
                while(*s)
                {
                        Putc(*(s++));
                        int t = m_Interval;
                        while(t--);
                }
      }
      
};
OStream &operator<<(OStream& stream,char c);
OStream &operator<<(OStream& stream,char*s);


extern UartOStream uartout;
extern LedOStream   led;
#endif
main.cpp
#include "myio.hpp"
#include "stm32l4xx_hal.h"

      char ADDR1;
      char ADDR2;
      char ADDR3;
      char ADDR4;
static UartOStream uartouttest4;
int main(void)
{
      UartOStream uartouttest2;
      UartOStream *uartouttest3 = new(UartOStream);
      HAL_Init();
      

      sprintf(ADDR1,"0x%08x",&uartout);
      sprintf(ADDR2,"0x%08x",&uartouttest2);
      sprintf(ADDR3,"0x%08x",uartouttest3);
      sprintf(ADDR4,"0x%08x",uartouttest4);
      
      uartout << "uartout" << "ADDR = " << ADDR1 <<'\r' <<'\n';
      uartouttest2 << "uartouttest2" << "ADDR = " << ADDR2 << "\r\n";
      *uartouttest3 << "uartouttest3" << "ADDR = " << ADDR3 << "\r\n";
      uartouttest4 << "uartouttest4" << "ADDR = " << ADDR4 << "\r\n";
      
      led.SetInterval(200000);
      led<<"101010101010101010101";
      //while(1);
      return 1;
}



Mandelbrot_Set 发表于 2015-10-26 11:09:14

初始化放在构造函数里是不对的!

moyanming2013 发表于 2015-10-26 11:40:48

能用OOP,不错。
优化的话,关键你用的编译器是哪个?

yanhaijian 发表于 2015-10-26 12:09:18

搞单片机玩C++的肯定是高手。

Mandelbrot_Set 发表于 2015-10-26 12:21:19

yanhaijian 发表于 2015-10-26 12:09
搞单片机玩C++的肯定是高手。

C++是大一必修课 :L

二货520 发表于 2015-10-26 12:25:58

:o:o:o:o:o不错哈

yanhaijian 发表于 2015-10-26 12:29:36

Mandelbrot_Set 发表于 2015-10-26 12:21
C++是大一必修课

单片机开发一般只用C,很少有人去研究C++。

Mandelbrot_Set 发表于 2015-10-26 13:09:22

yanhaijian 发表于 2015-10-26 12:29
单片机开发一般只用C,很少有人去研究C++。

嗯,是的

你好我好大家好! 发表于 2015-10-26 15:22:03

帮顶                     

你好我好大家好! 发表于 2015-10-26 15:22:25

帮顶                        
页: [1] 2 3
查看完整版本: [NUCLEO-L476RG开发] 先写段CPP玩玩,重载<<运算符