Practice 1
MyTime.h
class MyTime {
int hour;
int minute;
int second;
public:
MyTime(int h, int m, int s);
int getHour() { return hour;}
int getMinute() { return minute;}
int getSecond() { return second;}
};
MyTime.cpp
#include "MyTime.h"
MyTime:MyTime(int h, int m, int s) {
hour = h;
minute = m;
second = s;
}
Practice 2
Usually, when you create a class like MyTime class, the following constructor is automatically prepared by the compiler:
MyTime::MyTime(const MyTime &x) {
// copy all member variables from x
}
This is called copy constructor, but the detail of the copy constructor will be discussed in lecture later. so, you don't need to know what the copy constructor but students should try to implement a constructor which copies from an instance of the same class like:
Practice 3
When a constructor is explicitly called like MyTime(9, 30, 35), This call will create an instance of MyTime object. However, the created instance does not have a name..hence it's called "temporary object" (see C++ specification). Once this temporary object is created, this object is passed onto a default copy constructor to initialize MyTime c. So it's similar to :
MyTime tmp(9, 30, 35);
MyTime c = tmp;
You can check whether a temporally object is created by using the explicitly implemented copy constructor from Prac 2. Use cout << "message" in different constructors to find out how many different objects are created.
Practice 4
Here you can achieve the specified task using a constructor and a destructor for instance:
class FunctionStepIOLog {
const char *functionName;
public:
FunctionStepIOLog(const char *functionName) :functionName(functionName) {
cout << this->functionName << " started." << endl;
}
~FunctionStepIOLog() {
cout << this->functionName << " ended." << endl;
}
};
int read_from_file(const char *filename) {
FunctionStepIOLog("read_from_file");
FILE *fp;
char line[512];
/* read from a file and do something */
return 0;
}
Practice 5
You can do something like:
class AutoFreePtr {
char *ptr;
public:
AutoFreePtr():ptr(NULL) {}
~AutoFreePtr() {
if (ptr != NULL) delete[] ptr;
}
AutoFreePtr(char *ptr):ptr(NULL){
operator=(ptr);
}
char *operator=(char *ptr) {
if (this->ptr != NULL) delete[] this->ptr;
this->ptr = ptr;
return this->ptr;
}
operator char* () {
return ptr;
}
char &operator[](int index) {
return ptr[index];
}
};
Even more important is when there is a NULL pointer and returning elements will crash program. This can be tested with a simple boolean test ptr!=NULL or a check function bool isValid();
Practice 6
Try using union However, you won't be able to overload &operator[]... because&operator[] does not have any argument, hence you cannot overload...
#include <iostream>
#include <cmath>
using namespace std;
class AutoFreePtr {
union{
char *cptr;
int *iptr;
float *fptr;
double *dptr;
};
enum modes{CHAR, INT, FLOAT, DOUBLE};
int mode;
public:
AutoFreePtr(){
cptr = NULL;
}
AutoFreePtr(char *ptr){
printf("CHAR\n");
mode = CHAR;
cptr = NULL;
operator=(ptr);
}
~AutoFreePtr() {
cleanmem();
}
char* operator=(char *ptr) {
cleanmem();
mode = CHAR;
this->cptr = ptr;
return cptr;
}
int* operator=(int *ptr){
cleanmem();
mode = INT;
this->iptr = ptr;
return iptr;
}
operator char* () {
return cptr;
}
operator int* (){
return iptr;
}
char &operator[](int index) {
return cptr[index];
}
void cleanmem(){
switch(mode){
case CHAR:
if(cptr){
printf("CHAR DEL\n");
delete[] cptr;
break;
}
case INT:
if(iptr){
printf("INT DEL\n");
delete[] iptr;
break;
}
default:
printf("NO DEL\n");
delete[] cptr;
}
}
//int &operator[](int index){
//return iptr[index];
//}
};
int main() {
AutoFreePtr afp = new char[10];
afp = new char[10];
afp = new char[20];
afp = new char[20];
strcpy(afp, "aaabbbccc");
printf((char*)afp);
cout << afp[0] << endl;
int *aint = new int[10];
aint[0] = 9;
aint[1] = 8;
aint[2] = 7;
afp = aint;
cout << *((int *)afp + 1) << endl;
return 0;
}