C++ Primer Plus 第十二章答案 类和动态内存分配

简介: 只有聪明人才能看见的摘要~( ̄▽ ̄~)~

 复习题

//12.9
//1
a, 语法是正确的,但没有将str指针初始化,应该将指针设置成NULL或使用new来初始化它
b, 没有创建新的字符串,而只是复制了原有字符串的地址,应该使用new[]和strcpy()
c, 复制了字符串但没有分配存储空间,应该使用new char[len + 1]分配内存
//2
首先,当这种类型的对象过期时,对象的成员指针指向的数据仍然保留在内存中,导致占用
空间但是又不可访问,因为指针已经丢失。解决方法是让类的析构函数删除构造函数中new
分配的内存。其次,析构函数释放这种内存后,如果程序将这样的对象初始化为另一个对象,
析构函数会试图释放这些内存两次,这是因为将一个对象初始化为另一个对象的默认初始化
将复制指针值但不复制指向指针的数据,这样两个指针就指向同一个数据。解决方法是定义
一个复制构造函数,使初始化复制指向的数据。第三,将一个对象赋给另一个对象也会导致
两个指针指向相同的数据,解决方法是重载赋值运算符,使它复制数据而不是指针。
//3
C++自动提供下面的成员函数:
如果没有定义,将自动提供
默认构造函数,复制构造函数,赋值运算符,默认析构函数,地址运算符
默认构造函数不完成任何工作,但使得可以声明数组和未初始化的对象。
默认复制构造函数和默认赋值运算符使用成员赋值。
默认析构函数也不完成任何工作。
隐式地址运算符返回调用对象的人地址。(即this指针的值)
//4
#include<iostream>
#include<cstring>
using namespace std;
class nifty {
private:
  char* personality;
  int talents;
public:
  nifty();
  nifty(const char* s);
  nifty(const nifty& n);
  ~nifty() { delete[]personality; };
  nifty& operator=(const nifty& n);
  friend ostream& operator<<(ostream& os, const nifty& n);
};
nifty::nifty() {
  personality = nullptr;
  talents = 0;
}
nifty::nifty(const char* s) {
  personality = new char[strlen(s) + 1];
  strcpy(personality, s);
  talents = 0;
}
nifty::nifty(const nifty& n) {
  char* personality = new char[strlen(n.personality)];
  strcpy(personality, n.personality);
}
nifty& nifty::operator=(const nifty& n) {
  if (this == &n)
    return *this;
  delete[]personality;
  char* personality = new char[strlen(n.personality)];
  strcpy(personality, n.personality);
  return *this;
}
ostream& operator<<(ostream& os, const nifty& n) {
  os << n.personality << endl;
  os << n.talents << endl;
  return os;
}
//5
#1 默认构造函数
#2 构造函数,使用一个默认参数
#3 构造函数
#4 默认构造函数
#5 复制构造函数
#6 构造函数
#7 默认赋值运算符
#8 构造函数,默认赋值运算符
对于#5和#6有的编译器还会调用默认赋值运算符
应该定义一个复制数据(而不是地址)的赋值运算符

image.gif

practice1

使用strcpy总是有很多麻烦,换成strcpy_s可能麻烦更多

参考C++中strcpy()函数和strcpy_s()函数的使用及注意事项_strcpy_s函数_Leonardo Liu的博客-CSDN博客

#pragma once
//cow.h
#ifndef COW_H_
#define COW_H_
class Cow {
  char name[20];
  char* hobby;
  double weight;
public:
  Cow();
  Cow(const char* nm, const char* ho, double wt);
  Cow(const Cow& c);
  ~Cow() { delete[]hobby; }
  Cow& operator=(const Cow& c);
  void ShowCow()const;
  char* f() { return hobby; }//显示地址作为观察
};
#endif
//cow.cpp
#include"cow.h"
#include<iostream>
#include<cstring>
#pragma warning( disable : 4996)
using namespace std;
Cow::Cow() {
  strcpy(name, "");
  hobby = nullptr;
  weight = 0.0;
}
Cow::Cow(const char* nm, const char* ho, double wt) {
  strcpy(name, nm);
  hobby = new char[strlen(ho) + 1];
  strcpy(hobby, ho);
  weight = wt;
}
Cow::Cow(const Cow& c) {
  strcpy(name, c.name);
  hobby = new char[strlen(c.hobby) + 1];
  strcpy(hobby, c.hobby);
  weight = c.weight;
}
Cow& Cow::operator=(const Cow& c) {
  strcpy(name, c.name);
  delete[]hobby;
  hobby = new char[strlen(c.hobby) + 1];
  strcpy(hobby, c.hobby);
  weight = c.weight;
  return *this;
}
void Cow::ShowCow()const {
  cout << "Information of cow named " << name << endl;
  if (hobby == 0)
    cout << "Hobby is NULL" << endl;
  else
    cout << "Hobby: " << hobby << endl;
  cout << "Weight: " << weight << endl;
}
//main.cpp
#include<iostream>
#include"cow.h"
int main() {
  using namespace std;
  Cow cow1;
  cow1.ShowCow();
  cout << "Hobby address: " << (void*)cow1.f() << endl;
  cout << endl;
  char name[] = "cow one";
  Cow cow2(name, "drink", 180.5);
  cow2.ShowCow();
  cout << "Hobby address: " << (void*)cow2.f() << endl;
  cout << endl;
  Cow cow3 = cow2;
  cow3.ShowCow();
  cout << "Hobby address: " << (void*)cow3.f() << endl;
  cout << endl;
  Cow cow4;
  cow4 = cow3;
  cow4.ShowCow();
  cout << "Hobby address: " << (void*)cow4.f() << endl;
  cout << endl;
  return 0;
}

image.gif

practice2

唉,又要抄程序清单

//string2.h
#ifndef STRING2_H_
#define STRING2_H_
#include<iostream>
using namespace std;
class String {
  char* str;
  int len;
  static int num_strings;
  static const int CINLIM = 80;
public:
  String(const char* s);
  String();
  String(const String& s);
  ~String();
  int length()const { return len; }
  String& operator=(const String& s);
  String& operator=(const char* s);
  char& operator[](int i);
  const char& operator[](int i)const;
  friend bool operator<(const String& s1, const String& s2);
  friend bool operator>(const String& s1, const String& s2);
  friend bool operator==(const String& s1, const String& s2);
  friend ostream& operator<<(ostream& os, const String& s);
  friend istream& operator>>(istream& is, String& s);
  static int HowMany();
  friend String operator+(const String& s1, const String& s2);
  void stringlow();
  void stringup();
  int has(char c);
};
#endif
//string2.cpp
#include"string2.h"
#include<cstring>
#include<cctype>
#pragma warning( disable : 4996)
int String::num_strings = 0;
int String::HowMany() {
  return num_strings;
}
String::String(const char* s) {
  len = strlen(s);
  str = new char[len + 1];
  strcpy(str, s);
  num_strings++;
}
String::String() {
  len = 4;
  str = nullptr;
  num_strings++;
}
String::String(const String& s) {
  len = s.len;
  str = new char[len + 1];
  strcpy(str, s.str);
  num_strings++;
}
String::~String() {
  delete[]str;
  num_strings--;
}
String& String::operator=(const String& s) {
  if (this == &s)
    return *this;
  delete[]str;
  len = s.len;
  str = new char[len + 1];
  strcpy(str, s.str);
  return *this;
}
String& String::operator=(const char* s) {
  delete[]str;
  len = strlen(s);
  str = new char[len + 1];
  strcpy(str, s);
  return *this;
}
char& String::operator[](int i) {
  return str[i];
}
const char& String::operator[](int i)const {
  return str[i];
}
bool operator<(const String& s1, const String& s2) {
  return (strcmp(s1.str, s2.str) < 0);
}
bool operator>(const String& s1, const String& s2) {
  return s2 < s1;
}
bool operator==(const String& s1, const String& s2) {
  return (strcmp(s1.str, s2.str) == 0);
}
ostream& operator<<(ostream& os, const String& s) {
  os << s.str;
  return os;
}
istream& operator>>(istream& is, String& s) {
  char temp[String::CINLIM];
  is.get(temp, String::CINLIM);
  if (is)
    s = temp;
  while (is && is.get() != '\n')
    continue;
  return is;
}
String operator+(const String& s1, const String& s2) {
  String temp;
  temp.len = s1.len + s2.len;
  temp.str = new char[temp.len + 1];
  strcpy(temp.str, s1.str);
  strcat(temp.str, s2.str);
  return temp;
}
void String::stringlow() {
  for (int i = 0; i < len; i++)
    str[i] = tolower(str[i]);
}
void String::stringup() {
  for (int i = 0; i < len; i++)
    str[i] = toupper(str[i]);
}
int String::has(char c) {
  int sum = 0;
  for (int i = 0; i < len; i++)
    if (str[i] == c)
      sum++;
  return sum;
}
//main.cpp
#include<iostream>
using namespace std;
#include"string2.h"
int main() {
  String s1(" and I am a C++ student.");
  String s2 = "Please enter your name: ";
  String s3;
  cout << s2;
  cin >> s3;
  s2 = "My name is " + s3;
  cout << s2 << ".\n";
  s2 = s2 + s1;
  s2.stringup();
  cout << "The string\n" << s2 << "\ncontains " << s2.has('A')
    << " 'A' characters in it.\n";
  s1 = "red";
  String rgb[3] = { String(s1),String("green"),String("blue") };
  cout << "Enter the name of a primary color for mixing light: ";
  String ans;
  bool success = false;
  while (cin >> ans)
  {
    ans.stringlow();
    for (int i = 0; i < 3; i++)
    {
      if (ans == rgb[i])
      {
        cout << "That's right!\n";
        success = true;
        break;
      }
    }
    if (success)
      break;
    else
      cout << "Try again!\n";
  }
  cout << "Bye!\n";
  return 0;
}

image.gif

practice3

//stock.h
#pragma once
#ifndef STOCK3_H_
#define STOCK3_H_
#include<iostream>
class Stock {
  char* company;
  int shares;
  double share_val;
  double total_val;
  void set_tot() { total_val = shares * share_val; }
public:
  Stock();
  Stock(const char* c, long n = 0, double pr = 0.0);
  ~Stock();
  void buy(long num, double price);
  void sell(long num, double price);
  void updata(double price);
  const Stock& topval(const Stock& s)const;
  friend std::ostream& operator<<(std::ostream& os, const Stock& s);
};
#endif
//stock.cpp
#include"stock3.h"
#include<cstring>
#pragma warning(disable:4996)
using namespace std;
Stock::Stock() {
  company = nullptr;
  shares = 0;
  share_val = 0.0;
  total_val = 0.0;
}
Stock::Stock(const char* c, long n, double pr) {
  company = new char[strlen(c) + 1];
  strcpy(company, c);
  if (n < 0) {
    cout << "Number of shares can't be negative; "
      << company << "shares set to 0.\n";
    shares = 0;
  }
  else
    shares = n;
  share_val = pr;
  set_tot();
}
Stock:: ~Stock() {
  delete[]company;
}
void Stock::buy(long num, double price) {
  if (num < 0) {
    cout << "Number of shares purchased can't be negative."
      << "Transaction is aborted.\n";
  }
  else
  {
    shares += num;
    share_val = price;
    set_tot();
  }
}
void Stock::sell(long num, double price) {
  if (num < 0)
    cout << "Number of shares sold can't be negative."
    << "Transaction is aborted.";
  else if (num > shares)
    cout << "You can't sell more than you have!"
      << "Transaction is aborted!";
  else {
    shares -= num;
    share_val = price;
    set_tot();
  }
}
void Stock::updata(double price) {
  share_val = price;
  set_tot();
}
const Stock& Stock::topval(const Stock& s)const {
  if (s.total_val > total_val)
    return s;
  else
    return *this;
}
std::ostream& operator<<(std::ostream& os, const Stock& s) {
  ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield);
  streamsize prec = cout.precision(3);
  cout << "Company: " << s.company
    << "  Shares: " << s.shares << endl;
  cout << "  Shares Price: $" << s.share_val;
  cout.precision(2);
  cout << "  Total Worth: $" << s.total_val << endl;
  cout.setf(orig, ios_base::floatfield);
  cout.precision(prec);
  return os;
}
//main.cpp
#include"stock3.h"
#include<iostream>
const int STKS = 4;
int main() {
  using namespace std;
  Stock stocks[STKS] = {
    Stock("NanoSmart",12,20.0),
    Stock("Boffo Objects",200,2.0),
    Stock("Monolithic Obelisks",130,3.25),
    Stock("Fleep Enterprises",60,6.5)
  };
  cout << "Stock holding:\n";
  int st;
  for (st = 0; st < STKS; st++)
    cout << stocks[st];
  const Stock* top = &stocks[0];
  for (st = 1; st < STKS; st++)
    top = &top->topval(stocks[st]);
  cout << "\nMost valuable holding:\n";
  cout << *top << endl;
  return 0;
}

image.gif

practice4

#pragma once
//stack11.h
#ifndef STACK11_H_
#define STACK11_H_
typedef unsigned long Item;
class Stack {
  enum{MAX=10};
  Item* pitems;
  int size;
  int top;
public:
  Stack(int n = MAX);
  Stack(const Stack& s);
  ~Stack();
  bool isempty()const;
  bool isfull()const;
  bool push(const Item& item);
  bool pop(Item& item);
  Stack& operator=(const Stack& s);
};
#endif
//stack11.cpp
#include"stack11.h"
Stack::Stack(int n) {
  size = n;
  top = 0;
  pitems = new Item [size];
}
Stack::Stack(const Stack& s) {
  size = s.size;
  top = s.top;
  delete[]pitems;
  pitems = new Item[size];
  for (int i = 0; i < size; i++)
    pitems[i] = s.pitems[i];
}
Stack::~Stack() {
  delete[]pitems;
}
bool Stack::isempty()const {
  return top == 0;
}
bool Stack::isfull()const {
  return top == size;
}
bool Stack::push(const Item& item) {
  if (top == size)
    return false;
  else {
    pitems[top++] = item;
    return true;
  }
}
bool Stack::pop(Item& item) {
  if (top == 0)
    return false;
  else {
    item = pitems[--top];
    return true;
  }
}
Stack& Stack::operator=(const Stack& s) {
  if (this == &s)
    return *this;
  else {
    size = s.size;
    top = s.top;
    delete[]pitems;
    pitems = new Item[size];
    for (int i = 0; i < size; i++)
      pitems[i] = s.pitems[i];
  }
}
//stacker.cpp
#include<iostream>
#include"stack11.h"
#include<cctype>
void action(Stack& s);
//把对一个栈的操作分为三部分分别对三个栈完成,来检验复制构造函数和赋值运算符
//分开的部分,每一部分的操作要以q退出
int main() {
  using namespace std;
  Stack s1;
  action(s1);
  Stack s2 = s1;
  action(s2);
  Stack s3;
  s3 = s2;
  action(s3);
  cout << "Bye!\n";
  return 0;
}
void action(Stack& s) {
  using namespace std;
  char c;
  unsigned long po;
  cout << "Please enter A to add a purchase order,\n"
    << "P to process a PO, or Q to quit.\n";
  while (cin >> c && toupper(c) != 'Q') {
    while (cin.get() != '\n')
      continue;
    if (!isalpha(c)) {
      cout << '\a';
      continue;
    }
    switch (c) {
    case'A':
    case'a':cout << "Enter a PO number to add: ";
      cin >> po;
      if (s.isfull())
        cout << "Stack already full.\n";
      else
        s.push(po);
      break;
    case'P':
    case'p':if (s.isempty())
      cout << "Stack already empty.\n";
         else {
      s.pop(po);
      cout << "PO #" << po << "popped\n";
    }
         break;
    }
    cout << "Please enter A to add a purchase order,\n"
      << "P to process a PO, or Q to quit.\n";
  }
}

image.gif

practice5

//queue.h
#pragma once
class Customer {
  long arrive;
  int processtime;
public:
  Customer() { arrive = processtime = 0; }
  void set(long when);
  long when()const { return arrive; }
  int ptime()const { return processtime; }
};
typedef Customer Item;
class Queue {
  struct Node { Item item; Node* next; };
  enum { Q_SIZE = 0 };
  Node* front;
  Node* rear;
  int items;
  const int qsize;
  Queue(const Queue& q) :qsize(0) {}
  Queue& operator=(const Queue& q) { return *this; }
public:
  Queue(int qs = Q_SIZE);
  ~Queue();
  bool isempty()const;
  bool isfull()const;
  int queuecount()const;
  bool enqueue(const Item& item);
  bool dequeue(Item& item);
};
//queue.cpp
#include<cstdlib>
#include"queue.h"
using namespace std;
void Customer::set(long when) {
  arrive = when;
  processtime = rand() % 3 + 1;
}
Queue::Queue(int qs) :qsize(qs) {
  front = rear = nullptr;
  items = 0;
}
Queue::~Queue() {
  Node* temp;
  while (front != nullptr) {
    temp = front;
    front = front->next;
    delete temp;
  }
}
bool Queue::isempty()const {
  return items == 0;
}
bool Queue::isfull()const {
  return items == qsize;
}
int Queue::queuecount()const {
  return items;
}
bool Queue::enqueue(const Item& item) {
  if (isfull())
    return false;
  Node* add = new Node;
  add->item = item;
  add->next = nullptr;
  items++;
  if (front == nullptr)
    front = add;
  else
    rear->next = add;
  rear = add;
  return true;
}
bool Queue::dequeue(Item& item) {
  if (isempty())
    return false;
  item = front->item;
  items--;
  Node* temp = front;
  front = front->next;
  delete temp;
  if (items == 0)
    rear = nullptr;
  return true;
}
//bank.cpp
#include<iostream>
#include<ctime>
#include<cstdlib>
#include"queue.h"
using namespace std;
const int MIN_PER_HR = 60;
bool newcustomer(double x) {
  return(rand() * x / RAND_MAX < 1);
}
int main() {
  srand(time(0));
  int hours[5] = { 100,150,200,250,300 };
  for (int i = 0; i < 2; i++)
  {
    long cyclelimit = hours[i] * MIN_PER_HR;
    cout << "Hours: " << hours[i] << endl;
    for (int perhour = 10; perhour < 31; perhour++) 
    {
      Queue line(10);//line不能在外面定义,因为凡是循环里面用到的变量都需要重置
      //否则当turnaways出现后,line没有自动销毁,慢慢的就会累计错误
      //结果会出现负数,我找了半天才发现是因为在外面定义了line
      double min_per_cust = MIN_PER_HR / (double)perhour;
      Item temp;
      long turnaways = 0;
      long customers = 0;
      long served = 0;
      long sum_line = 0;
      int wait = 0;
      long line_wait = 0;
      for (int cycle = 0; cycle < cyclelimit; cycle++) 
      {
        if (newcustomer(min_per_cust)) 
        {
          if (line.isfull())
            turnaways++;
          else {
            customers++;
            temp.set(cycle);
            line.enqueue(temp);
          }
        }
        if (wait <= 0 && !line.isempty())
        {
          line.dequeue(temp);
          wait = temp.ptime();
          line_wait += (cycle - temp.when());
          served++;
        }
        if (wait > 0)
          wait--;
        sum_line += line.queuecount();
      }
      cout << "The average wait time by " << perhour
        << " customers every hours: " << double(line_wait) / served
        << " minuties\n";
    }
  }
  cout << "答案为18" << endl;
  cout << "Done!\n";
  return 0;
}

image.gif

practice 6

前两个文件不变

//bank.cpp
#include<iostream>
#include<ctime>
#include<cstdlib>
#include"queue.h"
using namespace std;
const int MIN_PER_HR = 60;
bool newcustomer(double x) {
  return(rand() * x / RAND_MAX < 1);
}
int main() {
  srand(time(0));
  int hours[5] = { 100,150,200,250,300 };
  for (int i = 0; i < 4; i++)
  {
    long cyclelimit = hours[i] * MIN_PER_HR * 6;
    //需要增加精度,cycle为10s
    cout << "Hours: " << hours[i] << endl;
    for (int perhour = 30; perhour < 41; perhour++)
    {
      Queue line1(10);
      Queue line2(10);
      double sec10_per_cust = MIN_PER_HR / (double)perhour * 6;
      Item temp1, temp2;
      long turnaways = 0;
      long customers = 0;
      long served = 0;
      long sum_line = 0;
      int wait1 = 0;
      int wait2 = 0;
      long line_wait = 0;
      for (int cycle = 0; cycle < cyclelimit; cycle++)
      {
        if (newcustomer(sec10_per_cust))
        {
          if (line1.queuecount() <= line2.queuecount())
          {
            if (line1.isfull());
            else
            {
              temp1.set(cycle);
              line1.enqueue(temp1);
            }
          }
          else
          {
            if (line2.isfull());
            else
            {
              temp2.set(cycle);
              line2.enqueue(temp2);
            }
          }
        }
        if (wait1 == 0 && !line1.isempty())
        {
          line1.dequeue(temp1);
          wait1 = temp1.ptime() * 6;
          line_wait += cycle - temp1.when();
          served++;
        }
        if (wait1 > 0)
          wait1--;
        if (wait2 == 0 && !line2.isempty())
        {
          line2.dequeue(temp2);
          wait2 = temp2.ptime() * 6;
          line_wait += cycle - temp2.when();
          served++;
        }
        if (wait2 > 0)
          wait2--;
      }
      cout << "The average wait time by " << perhour
        << " customers every hours: " << double(line_wait) / served / 6
        << " minuties\n";
    }
  }
  cout << "答案为34" << endl;
  cout << "Done!\n";
  return 0;
}

image.gif


目录
相关文章
|
7天前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
44 18
|
7天前
|
存储 编译器 数据安全/隐私保护
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
32 13
|
7天前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
26 5
|
7天前
|
存储 算法 搜索推荐
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
20 5
|
7天前
|
Serverless 编译器 C++
【C++面向对象——类的多态性与虚函数】计算图像面积(头歌实践教学平台习题)【合集】
本任务要求设计一个矩形类、圆形类和图形基类,计算并输出相应图形面积。相关知识点包括纯虚函数和抽象类的使用。 **目录:** - 任务描述 - 相关知识 - 纯虚函数 - 特点 - 使用场景 - 作用 - 注意事项 - 相关概念对比 - 抽象类的使用 - 定义与概念 - 使用场景 - 编程要求 - 测试说明 - 通关代码 - 测试结果 **任务概述:** 1. **图形基类(Shape)**:包含纯虚函数 `void PrintArea()`。 2. **矩形类(Rectangle)**:继承 Shape 类,重写 `Print
24 4
|
7天前
|
设计模式 IDE 编译器
【C++面向对象——类的多态性与虚函数】编写教学游戏:认识动物(头歌实践教学平台习题)【合集】
本项目旨在通过C++编程实现一个教学游戏,帮助小朋友认识动物。程序设计了一个动物园场景,包含Dog、Bird和Frog三种动物。每个动物都有move和shout行为,用于展示其特征。游戏随机挑选10个动物,前5个供学习,后5个用于测试。使用虚函数和多态实现不同动物的行为,确保代码灵活扩展。此外,通过typeid获取对象类型,并利用strstr辅助判断类型。相关头文件如&lt;string&gt;、&lt;cstdlib&gt;等确保程序正常运行。最终,根据小朋友的回答计算得分,提供互动学习体验。 - **任务描述**:编写教学游戏,随机挑选10个动物进行展示与测试。 - **类设计**:基类
23 3
|
2月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
70 2
|
2月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
123 5
|
2月前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
131 4
|
2月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
185 4