更新2:
它正在编译,但仍发出相同的警告。我很沮丧。
更新:
使用这些构造函数无效,并且仍然会产生相同的警告。据我了解,这就是变量的初始化方式。我的猜测是,我作为一个初学者会犯一个简单的错误。
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;
}
答案 0 :(得分:1)
检查控制流。
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_type和m_size未初始化。为什么不能只设置m_type ='/ 0'和m_size = 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;
}
}
您的所有其他警告也是如此。您需要确保所有构造都是针对每条路径进行的。
因此,在查看Ship类时,还要检查ctor的控制流。
此外,仅在Ship的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;
}
答案 1 :(得分:1)
您没有初始化成员变量。您将在之后分配给他们,然后使用垃圾自动对其进行初始化。
有两种方法可以初始化类成员变量:
我都喜欢,因为这是默认成员初始化的目的。使用默认成员初始化,以便默认构造函数按预期方式工作并具有合理的值,而用户定义的构造函数只需覆盖直接用作参数的变量即可。
//Note: Both of these are redundant. Pick one.
#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{0.0}; // The size of an engine, as a floating point number in double precision.
std::string m_type{}; // 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::Engine(const char* type, double size)
: m_size(size)
, m_type(type ? type : "") //Don't pass a nullptr to std::string's C-string constructor.
{}
答案 2 :(得分:-2)
问题是以下几行:
Engine m_engines[MAX_NUM_ENGINES];
但是您从未真正为引擎数组分配内存。所以问题在于,记住声明一个int数组时,您需要执行以下操作:
int* foo = new int[size of array];
在这种情况下,我将避免使用静态数组,因为您不知道要添加多少艘船。
还有另一个问题: 再次将m_engines初始化为一个数组,该数组将存储Engine对象,但是:
m_engines[0] = {};
您要使用字符串设置Engine对象类型的第一个元素?在我看来,这非常可疑。...