Question:
Specify, design, and implement a class that can be used to hold information about a musical note. A programmer should be able to set and retrieve the length of the note and the value of the note. The length of a note may be a six-teenth note, eighth note, quarter note, half note, or whole note. A value is specified by indicating how far the note lies above or below the A note that orchestras use in tuning. In counting “how far,” you should include both the white and black notes on a piano. For example, the note numbers for the octave beginning at middle C are shown here:
The default constructor should set a note to a middle C quarter note. Include member functions to set a note to a specified length and value. Write member functions to retrieve information about a note, including functions to tell you the letter of the note (A, B, C, etc.), whether the note is natural or sharp (i.e., white or black on the piano), and the frequency of a note in hertz. To calculate the frequency, use the formula
440
×
2
n
/
12
440\times2^{n/12}
440×2n/12, where n is the note number. Feel free to include other useful member functions.
My answer:
note.h
#ifndef NOTE_H
#define NOTE_H
enum note_length {six_teenth, eighth, quarter, half, whole};
class musical_note{
public:
musical_note(){
val = -9;
len = half;
};
void set_length(note_length a);
void set_value(int a);
void get_note_info();
double note_frequency();
private:
int val;
note_length len;
};
#endif
note.cpp
#include "note.h"
#include <iostream>
#include <cmath>
#include <assert.h>
void musical_note::set_length(note_length a){
len = a;
}
void musical_note::set_value(int a){
assert(a >= -9 && a <= 2);
val = a;
}
void musical_note::get_note_info(){
std::cout << "*********Musical Note Info**********" << std::endl;
std::cout << "Musical Note Length: ";
switch(len){
case six_teenth:
std::cout << "six_teenth" << std::endl;
break;
case eighth:
std::cout << "eighth" << std::endl;
break;
case quarter:
std::cout << "quarter" << std::endl;
break;
case half:
std::cout << "half" << std::endl;
break;
case whole:
std::cout << "whole" << std::endl;
break;
default:
std::cout << "Unknown error occurred!" << std::endl;
}
std::cout << "Musical Note Number: " << val << std::endl;
std::cout << "Musical Note Type: ";
switch(val){//可以考虑使用map容器
case -9:
std::cout << "C" << std::endl;
break;
case -8:
std::cout << "C#" << std::endl;
break;
case -7:
std::cout << "D" << std::endl;
break;
case -6:
std::cout << "C#" << std::endl;
break;
case -5:
std::cout << "E" << std::endl;
break;
case -4:
std::cout << "F" << std::endl;
break;
case -3:
std::cout << "F#" << std::endl;
break;
case -2:
std::cout << "G" << std::endl;
break;
case -1:
std::cout << "G#" << std::endl;
break;
case 0:
std::cout << "A" << std::endl;
break;
case 1:
std::cout << "A#" << std::endl;
break;
case 2:
std::cout << "B" << std::endl;
break;
default:
std::cout << "Unknown error occurred!" << std::endl;
}
std::cout << "Musical Note Frequency: " << note_frequency() << std::endl;
}
double musical_note::note_frequency(){
double tmp = (double)val;
return 440 * (pow(2, (tmp / 12)));
}
main.cpp
#include <iostream>
#include "note.h"
int main(){
musical_note test;
test.get_note_info();
std::cout << "update it......" << std::endl;
test.set_length(whole);
test.set_value(-1);
test.get_note_info();
}
结果:
Reference:
整理自 Data Structures and Other Objects Using C++ ( Fourth Edition ) Michael Main, Walter Savitch. p121