为什么编译器没有显示错误,当我有两个函数时,一个将采用基类,一个将派生类作为参数?

时间:2017-10-18 02:12:18

标签: c++ inheritance overloading

我有一个基类和派生类,它派生自基类。每个人都有一个朋友功能,如下所示重载operator+

#include <iostream>

using namespace std;

class base
{
    private:
        int x;

    public:
        base(int a) : x(a)
        {
        }

        void printx()
        {
            cout << "x : " << x << endl;
        }

        friend void operator+(int data, base &obj);
};

void operator+(int data, base &obj)
{
    obj.x = data + obj.x;
}

class derived : public base
{
    private:
        int y;

    public:
        derived(int a, int b) : base(a), y(b)
        {
        }

        void printy()
        {
            cout << "y : " << y << endl;
        }

        friend void operator+(int data, derived &obj);
};

void operator+(int data, derived &obj)
{
    operator+(data, obj);
    obj.y = data + obj.y;
}

int main()
{
    derived c(2, 3);

    4 + c;

    c.printx();
    c.printy();
}

我认为由于朋友的功能,编译器会抛出错误。

void operator+(int data, base &obj)
void operator+(int data, derived &obj)

将基类对象作为参数的函数也可以将派生类对象作为派生类的一部分。所以我认为编译器会显示错误,因为两个函数都可以将派生类对象作为参数。但是这个程序运行正常。任何人都可以解释为什么编译器没有显示错误吗?

2 个答案:

答案 0 :(得分:2)

简单回答:这两个函数没有冲突,因为它们没有相同的签名。

当您使用基本实例调用它时,它将不适合派生类引用,因此将调用@IBAction func signUpAction(_ sender: Any) { let email = emailTextField.text!.lowercased() let finalEmail = email.trimmingCharacters(in: .whitespacesAndNewlines) let location = locationTextField.text! let biography = biographyTextField.text! let username = usernameTextField.text! let password = passwordTextField.text! let firstLastName = firstLastNameTextField.text! let pictureData = UIImageJPEGRepresentation(self.userImageView.image!, 0.70) if finalEmail.isEmpty || location.isEmpty || biography.isEmpty || username.isEmpty || password.isEmpty { self.view.endEditing(true) let alertController = UIAlertController(title: "OOPS", message: " You must fill all the fields", preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) present(alertController, animated: true, completion: nil) }else { self.view.endEditing(true) authService.signUP(username: username, email: finalEmail, location: location, biography: biography, password: password, pictureData: pictureData as NSData!) } } var authService = AuthService() struct AuthService{ var dataBaseRef: DatabaseReference!{ return Database.database().reference() } var storageRef: StorageReference!{ return Storage.storage().reference() } func signUP(username: String, email: String, location: String, biography: String, password: String, pictureData: NSData!) { Auth.auth().createUser(withEmail: email, password: password) { (user, error) in if error == nil{ self.setUserInfo(user: user, username: username, location: location, biography: biography, password: password, pictureData: pictureData) }else{ print(error?.localizedDescription) } } } private func setUserInfo(user: User!, username: String, location: String, biography: String, password: String, pictureData: NSData!){ let imagePath = "profileImage\(user.uid)/userPic.jpg" let imageRef = storageRef.child(imagePath) let metaData = StorageMetadata() metaData.contentType = "image/jpeg" imageRef.putData(pictureData as Data, metadata: metaData){(newMetaData, error) in if error == nil{ let changeRequest = user.createProfileChangeRequest() changeRequest.displayName = username if let photoURL = newMetaData!.downloadURL(){ changeRequest.photoURL = photoURL } changeRequest.commitChanges(completion: { (error) in if error == nil{ self.saveUserInfo(user: user, username: username, location: location, biography: biography, password: password) print("user info set") }else{ print(error?.localizedDescription) } }) }else{ print(error?.localizedDescription) } } } private func saveUserInfo(user: User!, username: String, location: String, biography: String, password: String){ let userInfo = ["email": user.email!, "username": username, "location": location, "biography": biography, "uid": user.uid, "photoURL": String(describing: user.photoURL!)] let userRef = dataBaseRef.child("users").child(user.uid) userRef.setValue(userInfo) { (error, ref) in if error == nil{ print("USER SAVED") self.logIn(email: user.email!, password: password) }else{ print(error?.localizedDescription) } } } func logIn(email: String, password: String){ Auth.auth().signIn(withEmail: email, password: password) { (user, error) in if error == nil { if let user = user { print("\(user.displayName!) has been signed in") let appDel : AppDelegate = UIApplication.shared.delegate as! AppDelegate appDel.logUser() }else{ print(error?.localizedDescription) } } } }

当您使用派生实例调用一个时,基函数需要隐式转换,而派生函数则不需要,因此将调用operator+(int, base&)

参考:功能Overload Resolution,请参阅可行功能最佳可行功能部分。

  

1)至少有一个F1参数,其隐式转换优于F2参数的相应隐式转换

当然没有隐式转换比一次隐式转换“更好”,因此不会为一个devired对象调用operator+(int, derived&)

答案 1 :(得分:1)

对于import sys #import string #not sure if this is needed file_name=sys.argv[0] char= words = lines = theCount = aCount= 0 with open(file_name,'r') as in_file: for line in in_file: lines +=1 x = line.split() #use a variable to hold the split words #so that you can search in it words +=len(x) char +=len(line) if 'the' in x: #your original code was using "words" variable #that holds the "number of words" in the line, #therefore ints are not iterable theCount +=1 if 'a' in x: aCount +=1 #your original code using "a" variable #which did not initialized, #you have initialized "aCount" variable if 'an' in x: aCount +=1 #same as above print("Filename:", file_name) print("Number of lines:", lines) print("Number of characters:", char) print("Number of 'the'", theCount) print("Number of a/an:", aCount) overload resolution会尝试选择最好的一个; 4 + c;完全匹配,operator+(int data, derived &obj)需要隐式转换(从operator+(int data, base &obj)derived),然后选择base,此处不存在歧义错误。