C++ 如何正确初始化这些变量?

C++ 如何正确初始化这些变量?,c++,initialization,C++,Initialization,更新2: Variable 'sdds::Ship::m_engines' is uninitialized. Always initialize a member variable (type.6) Variable 'sdds::EngineShip::m_type' is uninitialized. Always initialize a member variable (type.6) Variable 'sdds::Engine::m_size' is uninitializ

更新2:

Variable 'sdds::Ship::m_engines' is uninitialized.  Always initialize a member variable (type.6)

Variable 'sdds::EngineShip::m_type' is uninitialized.  Always initialize a member variable (type.6)

Variable 'sdds::Engine::m_size' is uninitialized.  Always initialize a member variable (type.6)

Using uninitialized memory 'invalid' -> MAIN.CPP  Line 50
Using uninitialized memory 'invalid' -> MAIN.CPP  Line 77

Buffer overrun while writing to 'this->m_engines':  the writable size is '400' bytes, but '480' bytes might be written.  -> SHIP.CPP Line 91
它现在正在编译,但仍然给出相同的警告。我被难住了

更新:

Variable 'sdds::Ship::m_engines' is uninitialized.  Always initialize a member variable (type.6)

Variable 'sdds::EngineShip::m_type' is uninitialized.  Always initialize a member variable (type.6)

Variable 'sdds::Engine::m_size' is uninitialized.  Always initialize a member variable (type.6)

Using uninitialized memory 'invalid' -> MAIN.CPP  Line 50
Using uninitialized memory 'invalid' -> MAIN.CPP  Line 77

Buffer overrun while writing to 'this->m_engines':  the writable size is '400' bytes, but '480' bytes might be written.  -> SHIP.CPP Line 91
使用这些构造函数没有效果,仍然会产生相同的警告。据我所知,变量就是这样初始化的。我猜作为一个初学者,我犯了一个简单的错误

Ship::Ship()
{
    m_type[0] = '\0';
    m_engCnt = 0;
    m_engines[0] = {};
}

Engine::Engine()
{
    m_size = 0;
    m_type[0] = '\0';
}
警告:

Variable 'sdds::Ship::m_engines' is uninitialized.  Always initialize a member variable (type.6)

Variable 'sdds::EngineShip::m_type' is uninitialized.  Always initialize a member variable (type.6)

Variable 'sdds::Engine::m_size' is uninitialized.  Always initialize a member variable (type.6)

Using uninitialized memory 'invalid' -> MAIN.CPP  Line 50
Using uninitialized memory 'invalid' -> MAIN.CPP  Line 77

Buffer overrun while writing to 'this->m_engines':  the writable size is '400' bytes, but '480' bytes might be written.  -> SHIP.CPP Line 91
当我尝试以我在示例中看到的方式初始化变量时,编译器仍然会在Engine和Ship类上生成未初始化成员变量的警告。我知道这会导致更多的错误

以下是我尝试过的:

// Ship.cpp

Ship::Ship() {   m_type = '\0';   m_engCnt = 0;   m_engines = {}; }

// Engine.cpp

Engine::Engine() {   m_size = 0.0;   m_type = '\0'; }
我仍然收到未初始化的变量警告,我知道我分配内存不正确,因为我的整个程序没有通过一些成员变量验证。当它运行时,它还会在最后不断循环相同的错误消息

因为我对C++还很陌生,我很难找到我做错了什么,我确信我错了的是明显的愚蠢和愚蠢的东西。所以如果你能指出我脸上的鼻子,我会很感激的,这样我就可以脱掉裤子了

我的问题是:

  • 如何正确初始化这些变量
  • 内存地址/分配是否有明显的错误
  • 以下是违规代码:

    // Engine.h
    
    #pragma once
    #ifndef SDDS_ENGINE_H
    #define SDDS_ENGINE_H
    
    namespace sdds
    {
        const int   TYPE_MAX_SIZE = 30;                 // Max length of the type attribute in Engine class.
        
        class Engine
        {
            private:
                double  m_size;                         // The size of an engine, as a floating point number in double precision.
                char    m_type[TYPE_MAX_SIZE + 1];      // The engine model type, as an array of chars of size TYPE_MAX_SIZE.
    
            public:
                Engine() = default;                     // Default constructor.
                ~Engine() = default;                    // Default destructor.
                Engine(const char* type, double size);  // Custom constructor that rx's as params: engine type, size.
                double get() const;                     // Query that returns the size of the engine.
                void display() const;                   // Query that prints to the screen the content of an object in the format [SIZE] - liters - [TYPE] <ENDL>
        };
    }
    
    #endif
    
    
    
    ---
    
    // Engine.cpp
    
    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    #include <cstring>
    #include <iomanip>
    #include "Engine.h"
    
    using namespace std;
    
    namespace sdds
    {
        Engine::Engine(const char* type, double size)
        {
            // Validate explicit params:
            if (size > 0 && type[0] != '\0')
            {
                // Assign params to engine:
                strcpy(m_type, type);
                m_size = size;
            }
        }
        
        double Engine::get() const
        {
            return m_size;          // Return size of engine m_size.
        }
    
        void Engine::display() const
        {
            // Detect if Engine members are valid:
            if (m_size > 0 && m_type[0] != '\0')
            {
                // If valid, display m_size at precision 2, m_type:
                cout << fixed << setprecision(2) << m_size << " liters - " << m_type << endl;
            }
        }
    }
    
    
    ---
    
    // Ship.h
    
    #pragma once
    #ifndef SDDS_SHIP_H
    #define SDDS_SHIP_H
    #include "Engine.h"
    
    namespace sdds
    {
        const double    MIN_STD_POWER = 90.111;     // The minimum power of a ship, acc'g to the regulation.
        const double    MAX_STD_POWER = 99.999;     // The maximum power of a ship acc'g to the regulation.
        const int       MAX_NUM_ENGINES = 10;       // The maximum number of engines a ship can have.
    
        class Ship
        {
            Engine  m_engines[MAX_NUM_ENGINES];     // Statically allocated array of engines, of size MAX_NUM_ENGINES.
            char    m_type[TYPE_MAX_SIZE + 1];      // Ship model type, statically allocated arry of charss of TYPE_MAX_SIZE.
            int     m_engCnt;                       // The number of engines that are actually installed on the ship.
    
        public:
            Ship() = default;
            // ~Ship() = default;
            Ship(const char* type, const Engine arr[], int size);
            operator bool() const;
            bool operator<(double power) const;
            double calculatePower() const;
            void display() const;
            Ship& operator+=(Engine engine);
            
        };
        bool operator<(double power, const Ship& theShip);
    }
    
    #endif
    
    
    ---
    
    // Ship.cpp
    
    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    #include <iomanip>
    #include <cstring>
    #include "Ship.h"
    
    using namespace std;
    
    namespace sdds
    {
        //Ship::Ship()
        //{
    
        //}
    
        Ship::Ship(const char* type, const Engine engines[], int cnt)
        {
            // Validate params:
            if (type != nullptr && engines != nullptr && cnt > 0)
            {
                // If valid, store params in current instance:
                strcpy(m_type, type);           // Copy string from params to current instance of m_type.
                m_engCnt = cnt;                 // Current instance of m_engCnt is set to param cnt.
                
                // Iterate through current instance's m_engines[i] and assign engines[i].
                for (int i = 0; i < cnt; i++)
                {
                    m_engines[i] = engines[i];
                }
            }
            else 
            {
                // If params are invalid, set to a default empty state.
                m_type[0] = '\0';               // Default state for m_type = '\0'.
                m_engCnt = 0;                   // Default state for m_engCnt = 0.
            }
        }
    
        double Ship::calculatePower() const
        {
            double total_power = 0;
            for (int i = 0; i < m_engCnt; i++)
            {
                total_power += m_engines[i].get() * 5;
            }
            return total_power;
        }
    
        void Ship::display() const
        {
            if (*this)
            {
                cout << "No available data" << endl;
            }
            else
            {
                cout << m_type << "-";
                cout.setf(ios::fixed);
                cout.precision(2);
                cout.width(6);
                cout << calculatePower() << endl;
                cout.unsetf(ios::fixed);
                cout.precision(6);
                for (int i = 0; i < m_engCnt; i++)
                {
                    m_engines[i].display();
                }
            }
        }
    
        Ship::operator bool() const
        {
            // Explain in the reflection what happens if the keyword explicit is removed, and why is it necessary.
            bool valid = true;
            m_type[0] == '\0' && m_engCnt == 0 ? valid = false : valid = true;
            return valid;
        }
    
        Ship& Ship::operator+=(Engine engine)
        {
            // Make sure the number of engines is less than max allowed:
            if (m_engCnt < MAX_NUM_ENGINES)
            {
                if (m_type[0] == '\0')
                {
                    cout << "The object is not valid! Engine cannot be added!" << endl;     // Output error message.
                }
            }
            else
            {
                m_engines[m_engCnt + 1] = engine;
            }
            return *this;
        }
    
        bool Ship::operator<(double power) const
        {
            bool result = false;
            calculatePower() < power ? result = true : result = false;
            return result;
        }
    
        bool operator<(double power, const Ship& ship)
        {
            bool result = false;
            ship.calculatePower() > power ? result = false : result = true;
            return result;
    
        }
    
    }
    
    
    ---
    
    // Main.cpp
    
    #include <iostream>
    #include "Ship.h"
    #include "Ship.h"
    #include "Engine.h"
    #include "Engine.h"
    
    using namespace std;
    using namespace sdds;
    
    void printHeader(const char* title)
    {
        char oldFill = cout.fill('-');
        cout.width(40);
        cout << "" << endl;
    
        cout << "|> " << title << endl;
    
        cout.fill('-');
        cout.width(40);
        cout << "" << endl;
        cout.fill(oldFill);
    }
    
    int main()
    {
        {
            printHeader("T1: Testing Constants");
    
            cout << "TYPE_MAX_SIZE: " << sdds::TYPE_MAX_SIZE << endl;
            cout << "MIN_STD_POWER: " << sdds::MIN_STD_POWER << endl;
            cout << "MAX_STD_POWER: " << sdds::MAX_STD_POWER << endl;
            cout << endl;
        }
    
        {
            printHeader("T2: Testing Default Constructor");
    
            Ship invalid;
            invalid.display();
            invalid += Engine("D2", 2.1);
            cout << endl;
        }
    
        Engine engines[] = {
            Engine("V8", 4.4),
            Engine("V8", 5.0),
            Engine("Inline", 4.1),
            Engine("D3", 7.0),
            Engine("D0", 2.0),
            Engine("D1", 3.2),
        };
    
        {
            printHeader("T3: Testing Custom Constructor");
            
            Ship titanic("cruiser", engines, 6);
            titanic.display();
            cout << endl;
        }
    
        {
            printHeader("T4: Testing Conversion to Bool Operator");
            Ship invalid;
            Ship titanic("liner", engines, 1);
    
            if (invalid)
                cout << "1. Test Failed! Object should be invalid.\n";
            else
                cout << "1. Test succeeded!\n";
    
            if (titanic)
                cout << "2. Test succeeded!\n";
            else
                cout << "3. Test Failed! Object should be valid.\n";
            
            cout << endl;
        }
    
        {
            printHeader("T5: Testing += and < Operators");
    
            Ship titanic("liner", engines, 3);
    
            char type[]{ "D0" };
            while (titanic < sdds::MIN_STD_POWER)
            {
                type[1]++;
                cout << "Ship not up to standard. Required power: "
                     << sdds::MIN_STD_POWER << endl;
                titanic += Engine(type, 2.1);
            }
    
            titanic.display();
    
            if (sdds::MAX_STD_POWER < titanic)
                cout << "Too much power." << endl;
            else
                cout << "Ship doesn't exceed power regulation of: "
                     << sdds::MAX_STD_POWER << endl;
        }
    
        return 0;
    }
    
    //Engine.h
    #布拉格语一次
    #ifndef SDDS发动机
    #定义SDD\u引擎\u H
    命名空间SDD
    {
    const int TYPE_MAX_SIZE=30;//引擎类中TYPE属性的最大长度。
    类引擎
    {
    私人:
    double m_size;//引擎的大小,以双精度浮点数表示。
    char m_type[type_MAX_SIZE+1];//引擎模型类型,作为SIZE type_MAX_SIZE的字符数组。
    公众:
    Engine()=默认值;//默认构造函数。
    ~Engine()=default;//默认析构函数。
    引擎(const char*type,double size);//rx作为参数的自定义构造函数:引擎类型,大小。
    double get()const;//返回引擎大小的查询。
    void display()const;//以[SIZE]-l-[TYPE]格式向屏幕打印对象内容的查询
    };
    }
    #恩迪夫
    ---
    //Engine.cpp
    #定义\u CRT\u安全\u无\u警告
    #包括
    #包括
    #包括
    #包括“发动机.h”
    使用名称空间std;
    命名空间SDD
    {
    引擎::引擎(常量字符*类型,双倍大小)
    {
    //验证显式参数:
    如果(大小>0&&键入[0]!='\0')
    {
    //将参数分配给引擎:
    strcpy(m_类型,类型);
    m_尺寸=尺寸;
    }
    }
    双引擎::get()常量
    {
    return m_size;//返回引擎的大小m_size。
    }
    void引擎::display()常量
    {
    //检测引擎成员是否有效:
    如果(m_大小>0&&m_类型[0]!='\0')
    {
    //如果有效,以精度2显示m_大小,m_类型:
    
    不能检查您的控制流

        Engine::Engine(const char* type, double size)
        {
            // Validate explicit params:
            if (size > 0 && type[0] != '\0')
            {
                // Assign params to engine:
                strcpy(m_type, type);
                m_size = size;
            }
        }
    
    其他条件会发生什么?m_类型和m_大小未初始化。为什么不能只设置m_类型='/0'和m_大小=0

            Engine::Engine(const char* type, double size)
        {
            // Validate explicit params:
            if (size > 0 && type[0] != '\0')
            {
                // Assign params to engine:
                strcpy(m_type, type);
                m_size = size;
            }
            else
            {
                m_type = '/0';
                m_size = size;
            }
        }
    
    这同样适用于所有其他警告。您需要确保每个路径都发生了所有构造

    因此,在查看船舶级别时,也要检查控制流的ctor

    另外,您只在船舶的ctor中设置了m_engCnt。问题是您允许添加引擎(这也会增加此计数)。您需要考虑这一点

    Ship& Ship::operator+=(Engine engine)
    {
        // Make sure the number of engines is less than max allowed:
        if (m_engCnt < MAX_NUM_ENGINES)
        {
            if (m_type[0] == '\0')
            {
                cout << "The object is not valid! Engine cannot be added!" << endl;     // Output error message.
            }
        }
        else
        {
            m_engines[m_engCnt + 1] = engine;
            m_engCnt++;
        }
        return *this;
    }
    
    Ship&Ship::operator+=(引擎)
    {
    //确保发动机数量小于允许的最大值:
    如果(发动机数量<最大发动机数量)
    {
    如果(m_类型[0]='\0')
    {
    
    cout您没有初始化成员变量。您是在使用垃圾自动初始化成员变量后为其赋值

    初始化类成员变量有两种方法:

  • C++11默认成员初始化
  • 成员初始值设定项列表
  • 我更喜欢这两种方法,因为这是默认成员初始化的目的。使用默认成员初始化可以使默认构造函数按预期工作,并具有合理的值,而用户定义的构造函数只需要覆盖它们直接作为参数接收的变量

    //注意:这两个都是多余的。选择一个。
    #布拉格语一次
    #ifndef SDDS发动机
    #定义SDD\u引擎\u H
    命名空间SDD
    {
    const int TYPE_MAX_SIZE=30;//引擎类中TYPE属性的最大长度。
    类引擎
    {
    私人:
    double m_size{0.0};//引擎的大小,以双精度浮点数表示。
    std::string m_type{};//引擎模型类型,作为大小类型为_MAX_size的字符数组。
    公众:
    Engine()=默认值;//默认构造函数。
    ~Engine()=default;//默认析构函数。
    引擎(const char*type,double size);//rx作为参数的自定义构造函数:引擎类型,大小。
    double get()const;//返回引擎大小的查询。
    void display()const;//以[SIZE]-l-[TYPE]格式向屏幕打印对象内容的查询
    };
    }
    #恩迪夫
    引擎::引擎(常量字符*类型,双倍大小)
    :m_尺寸(尺寸)
    ,m_type(type?type:)//不要将null ptr传递给std::string的C-string构造函数。
    {}
    
    问题在于以下几行:

     Engine  m_engines[MAX_NUM_ENGINES];
    
    但实际上您从未为引擎数组分配过内存。所以问题是,请记住,当您声明int数组时,您需要执行以下操作:

    int* foo = new int[size of array];
    
    我会避免静电干扰