1- Operators in OpenCV
Function overloading
函数有相同的函数名,但是输入的参数不同,则可以分别定义不同情况的函数,而不需要反复定义新的函数名
- More convenient to code as follows
Operators for cv::Mat
matexample.cpp
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main()
{
float a[6]={1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f};
float b[6]={1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f};
cv::Mat A(2, 3, CV_32FC1, a);
cv::Mat B(3, 2, CV_32FC1, b);
cv::Mat C = A * B;
cout << "Matrix C = " << endl
<< C << endl;
return 0;
}
两个运算符被重载了:*
和 <<
CMakeList.cpp
cmake_minimum_required(VERSION 3.1)
set (CMAKE_CXX_STANDARD 11)
project(matexample)
find_package(OpenCV REQUIRED)
message(STATUS "OpenCV library status:")
message(STATUS " config: ${OpenCV_DIR}")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Declare the executable target built from your sources
add_executable(matexample matexample.cpp)
# Link your application with OpenCV libraries
target_link_libraries(matexample PRIVATE ${OpenCV_LIBS})
brew install openCV
cmake ..
make
Matrix C =
[9, 12;
18, 24]
Operator Overloading
- Customizes the C++ operators for operands of user-defined types
- Overloaded operators are functions with special function names
string demo.cpp
#include <iostream>
#include <string>
int main()
{
std::string s("Hello ");
s += "C";
s.operator+=(" and CPP!");
std::cout << s << std::endl;
return 0;
}
Hello C and CPP!
2- Operator Overloading
Operator Overloading
- Implementation of
operator+()
andoperator+=()
A+B操作:this + t
A += B 运算:this += t
Example1
time.hpp
#pragma once
#include <iostream>
class MyTime
{
int hours;
int minutes;
public:
MyTime(): hours(0), minutes(0){}
MyTime(int h, int m): hours(h), minutes(m){}
MyTime operator+(const MyTime & t) const
{
MyTime sum;
sum.minutes = this->minutes + t.minutes;
sum.hours = this->hours + t.hours;
sum.hours += sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
MyTime & operator+=(const MyTime & t)
{
this->minutes += t.minutes;
this->hours += t.hours;
this->hours += this->minutes / 60;
this->minutes %= 60;
return *this;
}
std::string getTime() const
{
return std::to_string(this->hours) + " hours and "
+ std::to_string(this->minutes) + " minutes.";
}
};
main.cpp
#include <iostream>
#include "time.hpp"
using namespace std;
int main()
{
MyTime t1(2, 40);
MyTime t2(1, 20);
std::cout << (t1 + t2).getTime() << std::endl;
t1 += t2; //operator
t1.operator+=(t2); //function
std::cout << t1.getTime() << endl;
return 0;
}
4 hours and 0 minutes.
5 hours and 20 minutes.
- If one operand is not MyTime, and is an
int
MyTime t1(2, 40);
MyTime t2 = t1 + 20;
- The function can be :
MyTime operator+(int m) const
{
MyTime sum;
sum.minutes = this->minutes + m;
sum.hours = this->hours;
sum.hours += sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
- We can even support the following operation to be more user friendly
MyTime t1(2, 40);
MyTime t2 = t1 + "one hour";
MyTime operator+(const std::string str) const
{
MyTime sum = *this;
if(str=="one hour")
sum.hours = this->hours + 1;
else
std::cerr<< "Only \"one hour\" is supported." << std::endl;
return sum;
}
Example 2
time.hpp
#pragma once
#include <iostream>
class MyTime
{
int hours;
int minutes;
public:
MyTime(): hours(0), minutes(0){}
MyTime(int h, int m): hours(h), minutes(m){}
MyTime operator+(const MyTime & t) const
{
MyTime sum;
sum.minutes = this->minutes + t.minutes;
sum.hours = this->hours + t.hours;
sum.hours += sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
MyTime & operator+=(const MyTime & t)
{
this->minutes += t.minutes;
this->hours += t.hours;
this->hours += this->minutes / 60;
this->minutes %= 60;
return *this;
}
MyTime operator+(int m) const
{
MyTime sum;
sum.minutes = this->minutes + m;
sum.hours = this->hours;
sum.hours += sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
MyTime & operator+=(int m)
{
this->minutes += m;
this->hours += this->minutes / 60;
this->minutes %= 60;
return *this;
}
MyTime operator+(const std::string str) const
{
MyTime sum = *this;
if(str=="one hour")
sum.hours = this->hours + 1;
else
std::cerr<< "Only \"one hour\" is supported." << std::endl;
return sum;
}
std::string getTime() const
{
return std::to_string(this->hours) + " hours and "
+ std::to_string(this->minutes) + " minutes.";
}
};
mai.cpp
#include <iostream>
#include "time.hpp"
using namespace std;
int main()
{
MyTime t1(2, 40);
std::cout << (t1 + 30).getTime() << std::endl;
t1 += 30; //operator
t1.operator+=(30); //function
std::cout << t1.getTime() << endl;
std::cout << (t1 + "one hour").getTime() << std::endl;
std::cout << (t1 + "two hour").getTime() << std::endl;
return 0;
}
3 hours and 10 minutes.
3 hours and 40 minutes.
4 hours and 40 minutes.
Only "one hour" is supported.
3 hours and 40 minutes.
- Overloaded operators is more user-friendly than functions
- But, wait…
t1 + 20; // operator
t1.operator+(20); // equivalent function invoking
- How about the expression
20 + t1;
3-friend
Functions
friend
functions
友元函数
- If we want that operator + can support (
int
+MyTime
)
MyTime t1(2, 40);
20 + t1;
- Let a friend function to help
- Friend funtions
(1) Declare in a class body
(2) Granted class access to members (including private members)
(3) But not members
- Again, friend functions are members! They just declared in the class body
class MyTime
{
public:
friend MyTime operator+(int m, const MyTime & t)
{
return t + m;
}
};
- A friend function is defined out of the class
- No
MyTime::
before its function name
class MyTime
{
public:
friend MyTime operator+(int m, const MyTime & t);
};
MyTime operator+(int m, const MyTime & t)
{
return t + m;
}
- Operator
<<
can also be overloaded - but in (
cout << t1;
) , the first operand isstd::ostream
, notMyTime
- To modify the definition of
std::ostream
? NO! - Use a friend function
friend std::ostream & operator<<(std::ostream & os, const MyTime & t)
{
std::string str = std::to_string(t.hours) + " hours and "
+ std::to_string(t.minutes) + " minutes.";
os << str;
return os;
}
friend std::istream & operator>>(std::istream & is, MyTime & t)
{
is >> t.hours >> t.minutes;
t.hours += t.minutes / 60;
t.minutes %= 60;
return is;
}
- return 返回值一定要是
std::i/ostream &
类型,否则无法链式输出,比如修改friend int operator << (...) {...return o}
std::cout << t1 << std::endl; => 0 << std::endl;
无法链式调用
Example3
time.hpp
#pragma once
#include <iostream>
class MyTime
{
int hours;
int minutes;
public:
MyTime(): hours(0), minutes(0){}
MyTime(int h, int m): hours(h), minutes(m){}
MyTime operator+(const MyTime & t) const
{
MyTime sum;
sum.minutes = this->minutes + t.minutes;
sum.hours = this->hours + t.hours;
sum.hours += sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
MyTime & operator+=(const MyTime & t)
{
this->minutes += t.minutes;
this->hours += t.hours;
this->hours += this->minutes / 60;
this->minutes %= 60;
return *this;
}
MyTime operator+(int m) const
{
MyTime sum;
sum.minutes = this->minutes + m;
sum.hours = this->hours;
sum.hours += sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
friend MyTime operator+(int m, const MyTime & t)
{
return t + m;
}
std::string getTime() const
{
return std::to_string(this->hours) + " hours and "
+ std::to_string(this->minutes) + " minutes.";
}
friend std::ostream & operator<<(std::ostream & os, const MyTime & t)
{
std::string str = std::to_string(t.hours) + " hours and "
+ std::to_string(t.minutes) + " minutes.";
os << str;
return os;
}
friend std::istream & operator>>(std::istream & is, MyTime & t)
{
is >> t.hours >> t.minutes;
t.hours += t.minutes / 60;
t.minutes %= 60;
return is;
}
};
main.cpp
#include <iostream>
#include "time.hpp"
using namespace std;
int main()
{
MyTime t1(2, 40);
std::cout << (30 + t1).getTime() << std::endl;
std::cout << t1 << std::endl;
std::cout << "Please input two integers:" << std::endl;
std::cin >> t1;
std::cout << t1 << std::endl;
return 0;
}
3 hours and 10 minutes.
2 hours and 40 minutes.
Please input two integers:
3 80
4 hours and 20 minutes.
4- User Defined Type Conversion
Operator type()
- Overloaded type conversion: convert the current type to another
//implicit conversion
operator int() const
{
std::cout << "operator int()" << std::endl;
return this->hours * 60 + this->minutes;
}
//explicit conversion
explicit operator float() const
{
std::cout << "explicit operator float()" << std::endl;
return float(this->hours * 60 + this->minutes);
}
MyTime t1(1, 20);
int minutes = t1; // implicit conversion
float f = float(t1); // explicit conversion
希望将MyTime
转换成一个整数,operator int()
加了explicit
: 转换必须是显式的,不能隐式的转换
- 如果:
MyTime t1(1, 20);
int minutes = t1; // implicit conversion
float f = t1; // explicit conversion
这样不会报错,因为自动先调用 operator int()
转换成一个整数,再强制转换成float
类型
Converting Constructor
- Convert another type to the current
MyTime(int m): hours(0), minutes(m)
{
std::cout << "Constructor MyTime(int)" << std::endl;
this->hours += this->minutes / 60;
this->minutes %= 60;
}
MyTime t2 = 70;
这里直接调用构造函数
Assignment operator overloading
- Convert another type to the current
MyTime & operator=(int m)
{
std::cout << "operator=(int)" << std::endl;
this->hours = 0;
this->minutes = m;
this->hours = this->minutes / 60;
this->minutes %= 60;
return *this;
}
MyTime t3;
t3 = 80;
这里是进行赋值操作
Be careful
- What is the difference in creating object
t2
andt3
初始化和赋值的区别
Example4
time.hpp
#pragma once
#include <iostream>
class MyTime
{
int hours;
int minutes;
public:
MyTime(): hours(0), minutes(0)
{
std::cout << "Constructor MyTime()" << std::endl;
}
MyTime(int m): hours(0), minutes(m)
{
std::cout << "Constructor MyTime(int)" << std::endl;
this->hours += this->minutes / 60;
this->minutes %= 60;
}
MyTime(int h, int m): hours(h), minutes(m)
{
std::cout << "Constructor MyTime(int,int)" << std::endl;
}
//implicit conversion
operator int() const
{
std::cout << "operator int()" << std::endl;
return this->hours * 60 + this->minutes;
}
//explicit conversion
explicit operator float() const
{
std::cout << "explicit operator float()" << std::endl;
return float(this->hours * 60 + this->minutes);
}
MyTime & operator=(int m)
{
std::cout << "operator=(int)" << std::endl;
this->hours = 0;
this->minutes = m;
this->hours = this->minutes / 60;
this->minutes %= 60;
return *this;
}
friend std::ostream & operator<<(std::ostream & os, const MyTime & t)
{
std::string str = std::to_string(t.hours) + " hours and "
+ std::to_string(t.minutes) + " minutes.";
os << str;
return os;
}
};
main.cpp
#include <iostream>
#include "time.hpp"
using namespace std;
int main()
{
MyTime t1(1, 20);
int minutes = t1; //implicit conversion
float f = float(t1); //explicit conversion.
std::cout << "minutes = " << minutes << std::endl;
std::cout << "minutes = " << f << std::endl;
MyTime t2 = 70;
std::cout << "t2 is " << t2 << std::endl;
MyTime t3;
t3 = 80;
std::cout << "t3 is " << t3 << std::endl;
return 0;
}
Constructor MyTime(int,int)
operator int()
explicit operator float()
minutes = 80
minutes = 80
Constructor MyTime(int)
t2 is 1 hours and 10 minutes.
Constructor MyTime()
operator=(int)
t3 is 1 hours and 20 minutes.
5- Increment and Decrement Operators
自增和自减运算符
Increment
- Two operators: prefix increment & postfix increment
// prefix increment
MyTime& operator++()
{
std::cout << "operator prefix increment" << std::endl;
this->minutes++;
this->hours += this->minutes / 60;
this->minutes = this->minutes % 60;
return *this;
}
// postfix increment
MyTime operator++(int)
{
std::cout << "operator postfix increment" << std::endl;
MyTime old = *this; // keep the old value
operator++(); // prefix increment
return old;
}
Example5
time.hpp
#pragma once
#include <iostream>
class MyTime
{
int hours;
int minutes;
public:
MyTime(): hours(0), minutes(0)
{
std::cout << "Constructor MyTime()" << std::endl;
}
MyTime(int m): hours(0), minutes(m)
{
std::cout << "Constructor MyTime(int)" << std::endl;
this->hours += this->minutes / 60;
this->minutes %= 60;
}
MyTime(int h, int m): hours(h), minutes(m)
{
std::cout << "Constructor MyTime(int,int)" << std::endl;
}
// prefix increment
MyTime& operator++()
{
this->minutes++;
this->hours += this->minutes / 60;
this->minutes = this->minutes % 60;
return *this;
}
// postfix increment
MyTime operator++(int)
{
MyTime old = *this; // keep the old value
operator++(); // prefix increment
return old;
}
friend std::ostream & operator<<(std::ostream & os, const MyTime & t)
{
std::string str = std::to_string(t.hours) + " hours and "
+ std::to_string(t.minutes) + " minutes.";
os << str;
return os;
}
};
main.cpp
#include <iostream>
#include "time.hpp"
using namespace std;
int main()
{
MyTime t1(1, 59);
MyTime t2 = t1++;
MyTime t3 = ++t1;
std::cout << "t1 is " << t1 << std::endl;
std::cout << "t2 is " << t2 << std::endl;
std::cout << "t3 is " << t3 << std::endl;
return 0;
}
Constructor MyTime(int,int)
operator postfix increment
operator prefix increment
operator prefix increment
t1 is 2 hours and 1 minutes.
t2 is 1 hours and 59 minutes.
t3 is 2 hours and 1 minutes.
Operators
- Operators which can be overloaded