【问题标题】:terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid在抛出 'std::logic_error' what() 的实例后调用终止:basic_string::_M_construct null 无效
【发布时间】:2019-02-08 00:32:15
【问题描述】:

以下是说明:

在第 10 章中,clockType 类旨在实现程序中的时间。除了小时、分钟和秒之外,某些应用程序可能需要您存储时区。
从类clockType 派生类extClockType 通过添加成员变量来存储时区。添加必要的成员函数和构造函数以使类正常工作。另外,编写成员函数和构造函数的定义。最后,编写一个测试程序来测试你的类。

这是我的文件:

clockType.h

//clockType.h, the specification file for the class clockType

#ifndef H_ClockType

#define H_ClockType

class clockType

{

public:

void setTime(int hours, int minutes, int seconds);

//Function to set the time.

//The time is set according to the parameters.

//Postcondition: hr = hours; min = minutes;

// sec = seconds

// The function checks whether the values of

// hours, minutes, and seconds are valid. If a

// value is invalid, the default value 0 is

// assigned.

​

void getTime(int& hours, int& minutes, int& seconds) const;

//Function to return the time.

//Postcondition: hours = hr; minutes = min;

// seconds = sec

​

void printTime() const;

//Function to print the time.

//Postcondition: The time is printed in the form

// hh:mm:ss.

​

void incrementSeconds();

//Function to increment the time by one second.

//Postcondition: The time is incremented by one

// second.

// If the before-increment time is 23:59:59, the

// time is reset to 00:00:00.

​

void incrementMinutes();

//Function to increment the time by one minute.

//Postcondition: The time is incremented by one

// minute.

// If the before-increment time is 23:59:53,

// the time is reset to 00:00:53.

​

void incrementHours();

//Function to increment the time by one hour.

//Postcondition: The time is incremented by one

// hour.

// If the before-increment time is 23:45:53, the

// time is reset to 00:45:53.

​

bool equalTime(const clockType& otherClock) const;

//Function to compare the two times.

//Postcondition: Returns true if this time is

// equal to otherClock; otherwise,

// returns false.

​

clockType(int hours, int minutes, int seconds);

//constructor with parameters

//The time is set according to the parameters.

//Postcondition: hr = hours; min = minutes;

// sec = seconds

// The constructor checks whether the values of

// hours, minutes, and seconds are valid. If a

// value is invalid, the default value 0 is

// assigned.

​

clockType();

//default constructor with parameters

//The time is set to 00:00:00.

//Postcondition: hr = 0; min = 0; sec = 0

private:

int hr; //variable to store the hours

int min; //variable to store the minutes

int sec; //variable to store the seconds

};

#endif

clockTypeImp.cpp

//Implementation File for the class clockType

#include <iostream>

#include "clockType.h"

​

using namespace std;

void clockType::setTime(int hours, int minutes, int seconds)

{

if (0 <= hours && hours < 24)

hr = hours;

else

hr = 0;

​

if (0 <= minutes && minutes < 60)

min = minutes;

else

min = 0;

​

if (0 <= seconds && seconds < 60)

sec = seconds;

else

sec = 0;

}

​

void clockType::getTime(int& hours, int& minutes,

int& seconds) const

{

hours = hr;

minutes = min;

seconds = sec;

}

​

void clockType::incrementHours()

{

hr++;

if (hr > 23)

hr = 0;

}

​

void clockType::incrementMinutes()

{

min++;

if (min > 59)

{

min = 0;

incrementHours();

}

}

​

void clockType::incrementSeconds()

{

sec++;

​

if (sec > 59)

{

sec = 0;

incrementMinutes();

}

}

​

void clockType::printTime() const

{

if (hr < 10)

cout << "0";

cout << hr << ":";

​

if (min < 10)

cout << "0";

cout << min << ":";

​

if (sec < 10)

cout << "0";

cout << sec;

}

​

bool clockType::equalTime(const clockType& otherClock) const

{

return (hr == otherClock.hr

&& min == otherClock.min

&& sec == otherClock.sec);

}

​

clockType::clockType(int hours, int minutes, int seconds)

{

if (0 <= hours && hours < 24)

hr = hours;

else

hr = 0;

​

if (0 <= minutes && minutes < 60)

min = minutes;

else

min = 0;

​

if (0 <= seconds && seconds < 60)

sec = seconds;

else

sec = 0;

}

​

clockType::clockType() //default constructor

{

hr = 0;

min = 0;

sec = 0;

}

​

(给出前两个文件)

(从这里开始是我创建代码的地方)

extClockType.h

​

#ifndef H_extClockType

#define H_extClockType

#include<iostream>

#include "clockType.h"

using namespace std;

​

class extClockType: public clockType

{

public:

extClockType();

extClockType(int, int, int, string);

void setTime(int hours, int minutes, int seconds, string zone);

string printTimezone();

string getTimezone();

private:

string zone;

};

#endif

extClockTypeImp.cpp

#include <iostream>

#include "clockType.h"

#include "extClockType.h"

​

using namespace std;

extClockType::extClockType(): clockType()

{

zone = "na";

}

​

extClockType::extClockType(int hours, int minutes, int seconds, string time_zone)

{

clockType::setTime(hours, minutes, seconds);

zone = time_zone;

}

void extClockType::setTime(int hours, int minutes, int seconds, string zone)

{

clockType::setTime(hours, minutes, seconds);

}

string extClockType::getTimezone()

{

return zone;

}

​

string extClockType::printTimezone()

{

clockType::printTime();

cout << " " << zone << endl;

return 0;

}

ma​​in.cpp

#include <string>

#include <iomanip>

#include <iostream>

#include "clockType.h"

#include "extClockType.h"

​

using namespace std;

​

int main()

{

extClockType time1(5, 10, 34, "CST");

cout << "Time 1: ";

time1.printTimezone();

cout<<endl;

extClockType time2;

time2.setTime(12, 45, 59, "PST");

cout<< "Time 2: ";

time2.printTimezone();

cout<<endl;

​

time2.incrementSeconds();

cout<< "After incrementing time 2 by one second, Time 2:";

time2.printTime();

}

​

这是我的错误信息:

Time 1: 05:10:34 CST

terminate called after throwing an instance of 'std::logic_error'

what(): basic_string::_M_construct null not valid

抱歉,帖子太长了,我只想展示我正在使用的所有文件。如果有人愿意尝试帮助我,那将是一个巨大的帮助!

【问题讨论】:

  • 欢迎来到 SO!请将源代码格式化为代码,以便读者理解。您可以突出显示代码并单击工具栏中的{} 按钮,或者将每行缩进四 (4) 个空格。请务必缩进代码本身,就好像它是一个实际的源文件一样。
  • 这是源代码中的错字吗?如果没有,错误很可能在这里。 cout
  • 同时删除过多的 cmets,因为它们除了添加噪音之外什么都不做。我们都知道代码行的作用。
  • @matthewfisher 我认为您指的是行 cout
  • @paulmckenzie cmets 在给我时已经在代码中,所以我没有删除它们。对不起。

标签: c++ class inheritance composition derived-class


【解决方案1】:

毕竟容易

string extClockType::printTimezone() {
   ... 
   return 0;
}

改成这个并更新原型:

void extClockType::printTimezone() {
   ... 
   return;
}

这试图构造一个带有 0 的 std::string 被解释为一个 nullptr。根据使用情况,返回值应该是无效的。

修复后,输出为:

时间 1:05:10:34 CST

时间 2:12:45:59 na

将时间 2 增加一秒后,时间 2:12:46:00

请注意,'na' 是

的结果
void setTime(int hours, int minutes, int seconds, string zone);

实际上并未设置“区域”成员变量。

【讨论】:

  • 感谢您的回复!所以我知道它试图构造一个 std::string 但我该如何在我的代码中解决这个问题?
  • 在答案中添加了正确的方法签名。如果我的回答有帮助,那么欢迎投票并接受它。
  • 我改成这样了:
  • void extClockType::printTimezone() { clockType::printTime(); cout
  • 我得到这个错误: extClockTypeImp.cpp:26:6: error: 'void extClockType::printTimezone()' 的原型与类'extClockType' void extClockType::printTimezone( ) ^ 在 extClockTypeImp.cpp:3:0 包含的文件中:extClockType.h:13:8: 错误:候选是:std::__cxx11::string extClockType::printTimezone() string printTimezone(); ^ bash:第 2 行:./a.out:没有这样的文件或目录
【解决方案2】:

一个错误是这样的:

string extClockType::printTimezone()
{
    clockType::printTime();
    cout << " " << zone << endl;
    return 0;  // This is not legal, converting an int to a std::string
}

返回时,您将返回 0,并且正在尝试将其转换为 std::stringstd::string 没有采用 int 参数的构造函数(在本例中为 0)。相反,会抛出异常。

您应该不返回任何内容(因此该函数应声明为返回 void),或者返回创建有效 std::string 的内容。

注意:为std::string 调用的构造函数是采用单个const char * 参数(see constructor (5)) 的构造函数。在这种情况下,0 被转换为nullptr,因此在返回时会尝试构造一个std::string(nullptr)

【讨论】:

  • Will be thrown is wrong. 虽然抛出异常是 UB 的有效表现形式。
  • "没有 std::string 的构造函数接受 int 参数(在本例中为 0)。相反,将引发异常。" -- 这个解释是不完整的:如果真的没有构造函数,代码将无法编译。
【解决方案3】:

这个错误仅仅意味着你调用了字符串构造函数:

std::string::string(const char *p);

使用NULL 指针,这是无效的。

使用调试器确切地找出您的代码在哪里执行此操作,并将其修复为不执行此操作。

【讨论】:

  • 还有第二个默认参数;虽然它实际上并没有改变任何东西。另外,请考虑提及做某事无效的结果是什么。
  • @Deduplicator 您的评论是正确的,但我不认为扩大答案以包含精确的细节实际上会帮助 OP,而是有机会混淆他。
  • 感谢您的反馈,非常感谢!有没有推荐的调试器?
  • @JarrettBowman 要使用的调试器取决于您使用的操作系统。在 Linux 上,使用 g++ -g ... 构建并使用 GDB。在 Windows 上,GDB 也可以工作,但我不确定效果如何。
猜你喜欢
  • 2023-01-17
  • 2022-01-11
  • 2019-10-26
  • 2017-04-11
  • 2017-12-13
  • 2012-07-27
  • 2020-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多